summaryrefslogtreecommitdiff
path: root/lib/Bytecode/Writer
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-02-10 05:45:09 +0000
committerChris Lattner <sabre@nondot.org>2007-02-10 05:45:09 +0000
commit77aae264a00671527842c9e0826abed43d1f77b1 (patch)
tree3298b4b349ff94bd3d97cdd688999249aff3718b /lib/Bytecode/Writer
parent2b8269f92bde5e09e92b54f5ff9cda93e9831b71 (diff)
downloadllvm-77aae264a00671527842c9e0826abed43d1f77b1.tar.gz
llvm-77aae264a00671527842c9e0826abed43d1f77b1.tar.bz2
llvm-77aae264a00671527842c9e0826abed43d1f77b1.tar.xz
Clone and specialize CreateSlotIfNeeded into CreateFunctionValueSlot to handle
function-local values. This speeds up bcwriting a small 2.2% (10.384->10.156s on 447.dealII), but paves the way for more important changes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34131 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bytecode/Writer')
-rw-r--r--lib/Bytecode/Writer/SlotCalculator.cpp163
-rw-r--r--lib/Bytecode/Writer/SlotCalculator.h1
2 files changed, 101 insertions, 63 deletions
diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp
index dfb87b48ec..b239aeb767 100644
--- a/lib/Bytecode/Writer/SlotCalculator.cpp
+++ b/lib/Bytecode/Writer/SlotCalculator.cpp
@@ -201,34 +201,110 @@ void SlotCalculator::processValueSymbolTable(const ValueSymbolTable *VST) {
CreateSlotIfNeeded(VI->second);
}
+void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
+ // Check to see if it's already in!
+ if (NodeMap.count(V)) return;
+
+ const Type *Ty = V->getType();
+ assert(Ty != Type::VoidTy && "Can't insert void values!");
+
+ if (const Constant *C = dyn_cast<Constant>(V)) {
+ if (isa<GlobalValue>(C)) {
+ // Initializers for globals are handled explicitly elsewhere.
+ } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
+ // Do not index the characters that make up constant strings. We emit
+ // constant strings as special entities that don't require their
+ // individual characters to be emitted.
+ assert(ModuleLevel.empty() &&
+ "How can a constant string be directly accessed in a function?");
+ // Otherwise, this IS a string: remember it.
+ if (!C->isNullValue())
+ ConstantStrings.push_back(cast<ConstantArray>(C));
+ } else {
+ // This makes sure that if a constant has uses (for example an array of
+ // const ints), that they are inserted also.
+ for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
+ I != E; ++I)
+ CreateSlotIfNeeded(*I);
+ }
+ }
+
+ unsigned TyPlane = getOrCreateTypeSlot(Ty);
+ if (Table.size() <= TyPlane) // Make sure we have the type plane allocated.
+ Table.resize(TyPlane+1, TypePlane());
+
+ // If this is the first value to get inserted into the type plane, make sure
+ // to insert the implicit null value.
+ if (Table[TyPlane].empty()) {
+ // Label's and opaque types can't have a null value.
+ if (Ty != Type::LabelTy && !isa<OpaqueType>(Ty)) {
+ Value *ZeroInitializer = Constant::getNullValue(Ty);
+
+ // If we are pushing zeroinit, it will be handled below.
+ if (V != ZeroInitializer) {
+ Table[TyPlane].push_back(ZeroInitializer);
+ NodeMap[ZeroInitializer] = 0;
+ }
+ }
+ }
+
+ // Insert node into table and NodeMap...
+ NodeMap[V] = Table[TyPlane].size();
+ Table[TyPlane].push_back(V);
+
+ SC_DEBUG(" Inserting value [" << TyPlane << "] = " << *V << " slot=" <<
+ NodeMap[V] << "\n");
+}
+
+
+unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
+ std::map<const Type*, unsigned>::iterator TyIt = TypeMap.find(Ty);
+ if (TyIt != TypeMap.end()) return TyIt->second;
+
+ // Insert into TypeMap.
+ unsigned ResultSlot = TypeMap[Ty] = Types.size();
+ Types.push_back(Ty);
+ SC_DEBUG(" Inserting type [" << ResultSlot << "] = " << *Ty << "\n" );
+
+ // Loop over any contained types in the definition, ensuring they are also
+ // inserted.
+ for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+ I != E; ++I)
+ getOrCreateTypeSlot(*I);
+
+ return ResultSlot;
+}
+
+
+
void SlotCalculator::incorporateFunction(const Function *F) {
assert((ModuleLevel.empty() ||
ModuleTypeLevel == 0) && "Module already incorporated!");
-
+
SC_DEBUG("begin processFunction!\n");
-
+
// Update the ModuleLevel entries to be accurate.
ModuleLevel.resize(getNumPlanes());
for (unsigned i = 0, e = getNumPlanes(); i != e; ++i)
ModuleLevel[i] = getPlane(i).size();
ModuleTypeLevel = Types.size();
-
+
// Iterate over function arguments, adding them to the value table...
for(Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
I != E; ++I)
- CreateSlotIfNeeded(I);
-
+ CreateFunctionValueSlot(I);
+
SC_DEBUG("Inserting Instructions:\n");
-
+
// Add all of the instructions to the type planes...
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
- CreateSlotIfNeeded(BB);
+ CreateFunctionValueSlot(BB);
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
if (I->getType() != Type::VoidTy)
- CreateSlotIfNeeded(I);
+ CreateFunctionValueSlot(I);
}
}
-
+
SC_DEBUG("end processFunction!\n");
}
@@ -236,17 +312,17 @@ void SlotCalculator::purgeFunction() {
assert((ModuleLevel.size() != 0 ||
ModuleTypeLevel != 0) && "Module not incorporated!");
unsigned NumModuleTypes = ModuleLevel.size();
-
+
SC_DEBUG("begin purgeFunction!\n");
-
+
// Next, remove values from existing type planes
for (unsigned i = 0; i != NumModuleTypes; ++i) {
// Size of plane before function came
unsigned ModuleLev = getModuleLevel(i);
assert(int(ModuleLev) >= 0 && "BAD!");
-
+
TypePlane &Plane = getPlane(i);
-
+
assert(ModuleLev <= Plane.size() && "module levels higher than elements?");
while (Plane.size() != ModuleLev) {
assert(!isa<GlobalValue>(Plane.back()) &&
@@ -255,11 +331,11 @@ void SlotCalculator::purgeFunction() {
Plane.pop_back(); // Shrink plane
}
}
-
+
// We don't need this state anymore, free it up.
ModuleLevel.clear();
ModuleTypeLevel = 0;
-
+
// Finally, remove any type planes defined by the function...
while (Table.size() > NumModuleTypes) {
TypePlane &Plane = Table.back();
@@ -271,41 +347,20 @@ void SlotCalculator::purgeFunction() {
NodeMap.erase(Plane.back()); // Erase from nodemap
Plane.pop_back(); // Shrink plane
}
-
+
Table.pop_back(); // Nuke the plane, we don't like it.
}
-
+
SC_DEBUG("end purgeFunction!\n");
}
-void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
- // Check to see if it's already in!
- if (NodeMap.count(V)) return;
-
+void SlotCalculator::CreateFunctionValueSlot(const Value *V) {
+ assert(!NodeMap.count(V) && "Function-local value can't be inserted!");
+
const Type *Ty = V->getType();
assert(Ty != Type::VoidTy && "Can't insert void values!");
+ assert(!isa<Constant>(V) && "Not a function-local value!");
- if (const Constant *C = dyn_cast<Constant>(V)) {
- if (isa<GlobalValue>(C)) {
- // Initializers for globals are handled explicitly elsewhere.
- } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
- // Do not index the characters that make up constant strings. We emit
- // constant strings as special entities that don't require their
- // individual characters to be emitted.
- assert(ModuleLevel.empty() &&
- "How can a constant string be directly accessed in a function?");
- // Otherwise, this IS a string: remember it.
- if (!C->isNullValue())
- ConstantStrings.push_back(cast<ConstantArray>(C));
- } else {
- // This makes sure that if a constant has uses (for example an array of
- // const ints), that they are inserted also.
- for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
- I != E; ++I)
- CreateSlotIfNeeded(*I);
- }
- }
-
unsigned TyPlane = getOrCreateTypeSlot(Ty);
if (Table.size() <= TyPlane) // Make sure we have the type plane allocated.
Table.resize(TyPlane+1, TypePlane());
@@ -326,28 +381,10 @@ void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
}
// Insert node into table and NodeMap...
- unsigned DestSlot = NodeMap[V] = Table[TyPlane].size();
+ NodeMap[V] = Table[TyPlane].size();
Table[TyPlane].push_back(V);
SC_DEBUG(" Inserting value [" << TyPlane << "] = " << *V << " slot=" <<
- DestSlot << "\n");
-}
+ NodeMap[V] << "\n");
+}
-
-unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
- std::map<const Type*, unsigned>::iterator TyIt = TypeMap.find(Ty);
- if (TyIt != TypeMap.end()) return TyIt->second;
-
- // Insert into TypeMap.
- unsigned ResultSlot = TypeMap[Ty] = Types.size();
- Types.push_back(Ty);
- SC_DEBUG(" Inserting type [" << ResultSlot << "] = " << *Ty << "\n" );
-
- // Loop over any contained types in the definition, ensuring they are also
- // inserted.
- for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
- I != E; ++I)
- getOrCreateTypeSlot(*I);
-
- return ResultSlot;
-}
diff --git a/lib/Bytecode/Writer/SlotCalculator.h b/lib/Bytecode/Writer/SlotCalculator.h
index bfc80489b2..229715936e 100644
--- a/lib/Bytecode/Writer/SlotCalculator.h
+++ b/lib/Bytecode/Writer/SlotCalculator.h
@@ -114,6 +114,7 @@ public:
private:
void CreateSlotIfNeeded(const Value *V);
+ void CreateFunctionValueSlot(const Value *V);
unsigned getOrCreateTypeSlot(const Type *T);
// processModule - Process all of the module level function declarations and