Revamp handling of labels. In particular, if we create a forward reference

for a basic block, use it when the block is defined instead of deleting it
and creating a new one.  Also, only create at most ONE forward reference
for any block, instead of one for each forward reference.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2004-07-14 06:28:35 +00:00
parent d94b6d3fa5
commit 2e2ed2995a

View File

@@ -149,6 +149,12 @@ static struct PerFunctionInfo {
std::map<ValID, PATypeHolder> LateResolveTypes; std::map<ValID, PATypeHolder> LateResolveTypes;
bool isDeclare; // Is this function a forward declararation? bool isDeclare; // Is this function a forward declararation?
/// BBForwardRefs - When we see forward references to basic blocks, keep
/// track of them here.
std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs;
std::vector<BasicBlock*> NumberedBlocks;
unsigned NextBBNum;
inline PerFunctionInfo() { inline PerFunctionInfo() {
CurrentFunction = 0; CurrentFunction = 0;
isDeclare = false; isDeclare = false;
@@ -156,11 +162,18 @@ static struct PerFunctionInfo {
inline void FunctionStart(Function *M) { inline void FunctionStart(Function *M) {
CurrentFunction = M; CurrentFunction = M;
NextBBNum = 0;
} }
void FunctionDone() { void FunctionDone() {
// If we could not resolve some blocks at parsing time (forward branches) NumberedBlocks.clear();
// resolve the branches now...
// Any forward referenced blocks left?
if (!BBForwardRefs.empty())
ThrowException("Undefined reference to label " +
BBForwardRefs.begin()->second.first.getName());
// Resolve all forward references now.
ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues); ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
// Make sure to resolve any constant expr references that might exist within // Make sure to resolve any constant expr references that might exist within
@@ -388,20 +401,64 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
return V; return V;
} }
static BasicBlock *getBBVal(const ValID &ID) { /// getBBVal - This is used for two purposes:
/// * If isDefinition is true, a new basic block with the specified ID is being
/// defined.
/// * If isDefinition is true, this is a reference to a basic block, which may
/// or may not be a forward reference.
///
static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
assert(inFunctionScope() && "Can't get basic block at global scope!"); assert(inFunctionScope() && "Can't get basic block at global scope!");
// See if the value has already been defined. std::string Name;
Value *V = getValNonImprovising(Type::LabelTy, ID); BasicBlock *BB = 0;
if (V) return cast<BasicBlock>(V); switch (ID.Type) {
default: ThrowException("Illegal label reference " + ID.getName());
case ValID::NumberVal: // Is it a numbered definition?
if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size())
CurFun.NumberedBlocks.resize(ID.Num+1);
BB = CurFun.NumberedBlocks[ID.Num];
break;
case ValID::NameVal: // Is it a named definition?
Name = ID.Name;
if (Value *N = lookupInSymbolTable(Type::LabelTy, Name))
BB = cast<BasicBlock>(N);
break;
}
BasicBlock *BB = new BasicBlock(); // See if the block has already been defined.
// Remember where this forward reference came from. FIXME, shouldn't we try if (BB) {
// to recycle these things?? // If this is the definition of the block, make sure the existing value was
CurModule.PlaceHolderInfo.insert(std::make_pair(BB, std::make_pair(ID, // just a forward reference. If it was a forward reference, there will be
llvmAsmlineno))); // an entry for it in the PlaceHolderInfo map.
if (isDefinition && !CurFun.BBForwardRefs.erase(BB))
// The existing value was a definition, not a forward reference.
ThrowException("Redefinition of label " + ID.getName());
ID.destroy(); // Free strdup'd memory.
return BB;
}
// Otherwise this block has not been seen before.
BB = new BasicBlock("", CurFun.CurrentFunction);
if (ID.Type == ValID::NameVal) {
BB->setName(ID.Name);
} else {
CurFun.NumberedBlocks[ID.Num] = BB;
}
// If this is not a definition, keep track of it so we can use it as a forward
// reference.
if (!isDefinition) {
// Remember where this forward reference came from.
CurFun.BBForwardRefs[BB] = std::make_pair(ID, llvmAsmlineno);
} else {
// The forward declaration could have been inserted anywhere in the
// function: insert it into the correct place now.
CurFun.CurrentFunction->getBasicBlockList().remove(BB);
CurFun.CurrentFunction->getBasicBlockList().push_back(BB);
}
InsertValue(BB, CurFun.LateResolveValues);
return BB; return BB;
} }
@@ -1660,18 +1717,10 @@ InstructionList : InstructionList Inst {
$$ = $1; $$ = $1;
} }
| /* empty */ { | /* empty */ {
// FIXME: Should check to see if there is a forward ref'd basic block that $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true);
// we can use and reuse it as appropriate. It doesn't make sense just to
// make forward ref'd blocks then discard them.
$$ = CurBB = new BasicBlock("", CurFun.CurrentFunction);
} }
| LABELSTR { | LABELSTR {
// FIXME: Should check to see if there is a forward ref'd basic block that $$ = CurBB = getBBVal(ValID::create($1), true);
// we can use and reuse it as appropriate. It doesn't make sense just to
// make forward ref'd blocks then discard them.
$$ = CurBB = new BasicBlock("", CurFun.CurrentFunction);
setValueName($$, $1);
InsertValue($$);
}; };
BBTerminatorInst : RET ResolvedVal { // Return with a result... BBTerminatorInst : RET ResolvedVal { // Return with a result...