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
This commit is contained in:
Chris Lattner 2007-02-10 05:45:09 +00:00
parent 2b8269f92b
commit 77aae264a0
2 changed files with 117 additions and 79 deletions

View File

@ -201,6 +201,82 @@ 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!");
@ -216,16 +292,16 @@ void SlotCalculator::incorporateFunction(const Function *F) {
// 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);
}
}
@ -278,33 +354,12 @@ void SlotCalculator::purgeFunction() {
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!");
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);
}
}
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.
@ -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;
}

View File

@ -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