add support for incorporating and purging functions to the value enumerator

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36465 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2007-04-26 03:50:57 +00:00
parent 51d5f29c3f
commit 8d35c79f27
3 changed files with 38 additions and 98 deletions

View File

@@ -478,10 +478,12 @@ static void WriteModuleConstants(const ValueEnumerator &VE,
} }
} }
/// WriteFunction - Emit a function body to the module stream.
static void WriteFunction(const Function &F, ValueEnumerator &VE, static void WriteFunction(const Function &F, ValueEnumerator &VE,
BitstreamWriter &Stream) { BitstreamWriter &Stream) {
VE.incorporateFunction(F);
VE.purgeFunction();
} }
/// WriteTypeSymbolTable - Emit a block for the specified type symtab. /// WriteTypeSymbolTable - Emit a block for the specified type symtab.

View File

@@ -53,8 +53,13 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
// the module symbol table can refer to them... // the module symbol table can refer to them...
EnumerateValueSymbolTable(M->getValueSymbolTable()); EnumerateValueSymbolTable(M->getValueSymbolTable());
// Enumerate types used by function bodies. // Enumerate types used by function bodies and argument lists.
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
I != E; ++I)
EnumerateType(I->getType());
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
@@ -156,109 +161,39 @@ int ValueEnumerator::PurgeAggregateValues() {
return Values.size(); return Values.size();
} }
void ValueEnumerator::incorporateFunction(const Function &F) {
ModuleLevel = Values.size();
// Adding function arguments to the value table.
#if 0 for(Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end();
void SlotCalculator::incorporateFunction(const Function *F) {
SC_DEBUG("begin processFunction!\n");
// 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) I != E; ++I)
CreateFunctionValueSlot(I); EnumerateValue(I);
SC_DEBUG("Inserting Instructions:\n"); // Add all function-level constants to the value table.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I)
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
OI != E; ++OI) {
if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
isa<InlineAsm>(*OI))
EnumerateValue(*OI);
}
}
// Add all of the instructions to the type planes... // Add all of the instructions.
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
CreateFunctionValueSlot(BB); EnumerateValue(BB);
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
if (I->getType() != Type::VoidTy) if (I->getType() != Type::VoidTy)
CreateFunctionValueSlot(I); EnumerateValue(I);
}
}
SC_DEBUG("end processFunction!\n");
}
void SlotCalculator::purgeFunction() {
SC_DEBUG("begin purgeFunction!\n");
// Next, remove values from existing type planes
for (DenseMap<unsigned,unsigned,
ModuleLevelDenseMapKeyInfo>::iterator I = ModuleLevel.begin(),
E = ModuleLevel.end(); I != E; ++I) {
unsigned PlaneNo = I->first;
unsigned ModuleLev = I->second;
// Pop all function-local values in this type-plane off of Table.
TypePlane &Plane = getPlane(PlaneNo);
assert(ModuleLev < Plane.size() && "module levels higher than elements?");
for (unsigned i = ModuleLev, e = Plane.size(); i != e; ++i) {
NodeMap.erase(Plane.back()); // Erase from nodemap
Plane.pop_back(); // Shrink plane
}
}
ModuleLevel.clear();
// Finally, remove any type planes defined by the function...
while (Table.size() > NumModuleTypes) {
TypePlane &Plane = Table.back();
SC_DEBUG("Removing Plane " << (Table.size()-1) << " of size "
<< Plane.size() << "\n");
for (unsigned i = 0, e = Plane.size(); i != e; ++i)
NodeMap.erase(Plane[i]); // Erase from nodemap
Table.pop_back(); // Nuke the plane, we don't like it.
}
SC_DEBUG("end purgeFunction!\n");
}
inline static bool hasImplicitNull(const Type* Ty) {
return Ty != Type::LabelTy && Ty != Type::VoidTy && !isa<OpaqueType>(Ty);
}
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!");
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 noticed of this type within this function,
// remember the module level for this type plane in ModuleLevel. This reminds
// us to remove the values in purgeFunction and tells us how many to remove.
if (TyPlane < NumModuleTypes)
ModuleLevel.insert(std::make_pair(TyPlane, Table[TyPlane].size()));
// 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 (hasImplicitNull(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... void ValueEnumerator::purgeFunction() {
NodeMap[V] = Table[TyPlane].size(); /// Remove purged values from the ValueMap.
Table[TyPlane].push_back(V); for (unsigned i = ModuleLevel, e = Values.size(); i != e; ++i)
ValueMap.erase(Values[i].first);
SC_DEBUG(" Inserting value [" << TyPlane << "] = " << *V << " slot=" << Values.resize(ModuleLevel);
NodeMap[V] << "\n");
} }
#endif

View File

@@ -43,6 +43,9 @@ private:
ValueMapType ValueMap; ValueMapType ValueMap;
ValueList Values; ValueList Values;
/// When a function is incorporated, this is the size of the Values list
/// before incorporation.
unsigned ModuleLevel;
ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT ValueEnumerator(const ValueEnumerator &); // DO NOT IMPLEMENT
void operator=(const ValueEnumerator &); // DO NOT IMPLEMENT void operator=(const ValueEnumerator &); // DO NOT IMPLEMENT
@@ -72,7 +75,7 @@ public:
/// incorporateFunction/purgeFunction - If you'd like to deal with a function, /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
/// use these two methods to get its data into the ValueEnumerator! /// use these two methods to get its data into the ValueEnumerator!
/// ///
void incorporateFunction(const Function *F); void incorporateFunction(const Function &F);
void purgeFunction(); void purgeFunction();
private: private: