diff options
author | Chris Lattner <sabre@nondot.org> | 2007-02-10 05:45:09 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-02-10 05:45:09 +0000 |
commit | 77aae264a00671527842c9e0826abed43d1f77b1 (patch) | |
tree | 3298b4b349ff94bd3d97cdd688999249aff3718b /lib/Bytecode | |
parent | 2b8269f92bde5e09e92b54f5ff9cda93e9831b71 (diff) | |
download | external_llvm-77aae264a00671527842c9e0826abed43d1f77b1.zip external_llvm-77aae264a00671527842c9e0826abed43d1f77b1.tar.gz external_llvm-77aae264a00671527842c9e0826abed43d1f77b1.tar.bz2 |
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')
-rw-r--r-- | lib/Bytecode/Writer/SlotCalculator.cpp | 163 | ||||
-rw-r--r-- | lib/Bytecode/Writer/SlotCalculator.h | 1 |
2 files changed, 101 insertions, 63 deletions
diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp index dfb87b4..b239aeb 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 bfc8048..2297159 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 |