[llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y

Chris Lattner lattner at cs.uiuc.edu
Tue Jul 13 23:29:25 PDT 2004



Changes in directory llvm/lib/AsmParser:

llvmAsmParser.y updated: 1.179 -> 1.180

---
Log message:

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.


---
Diffs of the changes:  (+71 -22)

Index: llvm/lib/AsmParser/llvmAsmParser.y
diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.179 llvm/lib/AsmParser/llvmAsmParser.y:1.180
--- llvm/lib/AsmParser/llvmAsmParser.y:1.179	Tue Jul 13 20:33:11 2004
+++ llvm/lib/AsmParser/llvmAsmParser.y	Wed Jul 14 01:28:35 2004
@@ -149,6 +149,12 @@
   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 @@
 
   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 @@
   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 @@
     $$ = $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...





More information about the llvm-commits mailing list