diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-07-14 06:28:35 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-07-14 06:28:35 +0000 |
| commit | 4accae9c3ec5b86b06c768e9b88a2481006a0be1 (patch) | |
| tree | 5881716f6eef200b6970a68fc736f15e4938032e | |
| parent | 590b5f12db00f15f0627daa9e6a1a2411574db3b (diff) | |
| download | bcm5719-llvm-4accae9c3ec5b86b06c768e9b88a2481006a0be1.tar.gz bcm5719-llvm-4accae9c3ec5b86b06c768e9b88a2481006a0be1.zip | |
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.
llvm-svn: 14807
| -rw-r--r-- | llvm/lib/AsmParser/llvmAsmParser.y | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y index 029182c9884..4724a0f1030 100644 --- a/llvm/lib/AsmParser/llvmAsmParser.y +++ b/llvm/lib/AsmParser/llvmAsmParser.y @@ -149,6 +149,12 @@ static struct PerFunctionInfo { std::map<ValID, PATypeHolder> LateResolveTypes; 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() { CurrentFunction = 0; isDeclare = false; @@ -156,11 +162,18 @@ static struct PerFunctionInfo { inline void FunctionStart(Function *M) { CurrentFunction = M; + NextBBNum = 0; } void FunctionDone() { - // If we could not resolve some blocks at parsing time (forward branches) - // resolve the branches now... + NumberedBlocks.clear(); + + // 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); // 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; } -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!"); - // See if the value has already been defined. - Value *V = getValNonImprovising(Type::LabelTy, ID); - if (V) return cast<BasicBlock>(V); + std::string Name; + BasicBlock *BB = 0; + 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(); - // Remember where this forward reference came from. FIXME, shouldn't we try - // to recycle these things?? - CurModule.PlaceHolderInfo.insert(std::make_pair(BB, std::make_pair(ID, - llvmAsmlineno))); + // See if the block has already been defined. + if (BB) { + // If this is the definition of the block, make sure the existing value was + // just a forward reference. If it was a forward reference, there will be + // 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; } @@ -1660,18 +1717,10 @@ InstructionList : InstructionList Inst { $$ = $1; } | /* empty */ { - // FIXME: Should check to see if there is a forward ref'd basic block that - // 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); + $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++), true); } | LABELSTR { - // FIXME: Should check to see if there is a forward ref'd basic block that - // 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($$); + $$ = CurBB = getBBVal(ValID::create($1), true); }; BBTerminatorInst : RET ResolvedVal { // Return with a result... |

