Added an option to get the next and previous instructions across basic blocks
authorBenjamin Segovia <segovia.benjamin@gmail.com>
Mon, 16 Apr 2012 01:28:57 +0000 (18:28 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 10 Aug 2012 23:16:25 +0000 (16:16 -0700)
backend/src/ir/context.cpp
backend/src/ir/function.cpp
backend/src/ir/function.hpp
backend/src/ir/instruction.hpp

index 1652b2d..838ce9e 100644 (file)
@@ -51,7 +51,6 @@ namespace ir {
     // Check first that all branch instructions point to valid labels
     for (auto it = usedLabels->begin(); it != usedLabels->end(); ++it)
       GBE_ASSERTM(*it != LABEL_IS_POINTED, "A label is used and not defined");
-    // std::cout << *fn << std::endl;
     fn->computeCFG();
     GBE_DELETE(usedLabels);
     const StackElem elem = fnStack.back();
index 2bf4ac6..a91cec3 100644 (file)
@@ -73,11 +73,19 @@ namespace ir {
   }
 
   void Function::computeCFG(void) {
-    // Clear possible previously computed CFG
-    this->foreachBlock([this](BasicBlock &bb) {
+    // Clear possible previously computed CFG and compute the direct
+    // predecessors and successors
+    BasicBlock *prev = NULL;
+    this->foreachBlock([this, &prev](BasicBlock &bb) {
       bb.successors.clear();
       bb.predecessors.clear();
+      if (prev != NULL) {
+        prev->nextBlock = &bb;
+        bb.prevBlock = prev;
+      }
+      prev = &bb;
     });
+
     // Update it. Do not forget that a branch can also jump to the next block
     BasicBlock *jumpToNext = NULL;
     this->foreachBlock([this, &jumpToNext](BasicBlock &bb) {
@@ -143,6 +151,7 @@ namespace ir {
 
   BasicBlock::BasicBlock(Function &fn) : fn(fn) {
     this->first = this->last = NULL;
+    this->nextBlock = this->prevBlock = NULL;
   }
   BasicBlock::~BasicBlock(void) {
     this->foreach([this] (Instruction &insn) {
@@ -150,6 +159,48 @@ namespace ir {
     });
   }
 
+#define DECL_GET_PRED \
+  if (predecessor != NULL) return predecessor; \
+  if (stayInBlock == true) return NULL; \
+  const BasicBlock *parent = this->getParent(); \
+  const BasicBlock *prev = parent->getPrevBlock(); \
+  while (prev) { \
+    Instruction *last = prev->getLastInstruction(); \
+    if (last) return last; \
+    prev = prev->getPrevBlock(); \
+  } \
+  return NULL;
+
+  Instruction *Instruction::getPredecessor(bool stayInBlock) {
+    DECL_GET_PRED;
+  }
+  const Instruction *Instruction::getPredecessor(bool stayInBlock) const {
+    DECL_GET_PRED;
+  }
+
+#undef DECL_GET_PRED
+
+#define DECL_GET_SUCC \
+  if (successor != NULL) return successor; \
+  if (stayInBlock == true) return NULL; \
+  const BasicBlock *parent = this->getParent(); \
+  const BasicBlock *next = parent->getNextBlock(); \
+  while (next) { \
+    Instruction *first = next->getFirstInstruction(); \
+    if (first) return first; \
+    next = next->getNextBlock(); \
+  } \
+  return NULL;
+
+  Instruction *Instruction::getSuccessor(bool stayInBlock) {
+    DECL_GET_SUCC;
+  }
+  const Instruction *Instruction::getSuccessor(bool stayInBlock) const {
+    DECL_GET_SUCC;
+  }
+
+#undef DECL_GET_SUCC
+
 } /* namespace ir */
 } /* namespace gbe */
 
index 354dba5..165bc6f 100644 (file)
@@ -82,14 +82,21 @@ namespace ir {
     /*! Get the parent function */
     Function &getParent(void) { return fn; }
     const Function &getParent(void) const { return fn; }
-    /*! Get the successors */
+    /*! Get the next and previous allocated block */
+    BasicBlock *getNextBlock(void) const { return this->nextBlock; }
+    BasicBlock *getPrevBlock(void) const { return this->prevBlock; }
+    /*! Get the first and last instructions */
+    Instruction *getFirstInstruction(void) const { return this->first; }
+    Instruction *getLastInstruction(void) const { return this->last; }
+    /*! Get successors and predecessors */
     const BlockSet &getSuccessorSet(void) const { return successors; }
-    /*! Get the predecessors */
     const BlockSet &getPredecessorSet(void) const { return predecessors; }
   private:
     friend class Function; //!< Owns the basic blocks
     BlockSet predecessors; //!< Incoming blocks
     BlockSet successors;   //!< Outgoing blocks
+    BasicBlock *nextBlock; //!< Block allocated just after this one
+    BasicBlock *prevBlock; //!< Block allocated just before this one
     Instruction *first;    //!< First instruction in the block
     Instruction *last;     //!< Last instruction in the block
     Function &fn;          //!< Function the block belongs to
index 3befd02..31acd17 100644 (file)
@@ -96,12 +96,12 @@ namespace ir {
     /*! Get the register of the given destination */
     RegisterData getSrcData(uint32_t ID = 0u) const;
     /*! Get / set the previous instruction in the stream */
-    Instruction *getPredecessor(void) { return predecessor; }
-    const Instruction *getPredecessor(void) const { return predecessor; }
+    Instruction *getPredecessor(bool stayInBlock = true);
+    const Instruction *getPredecessor(bool stayInBlock = true) const;
     void setPredecessor(Instruction *insn) { this->predecessor = insn; }
     /*! Get / set the next instruction in the stream */
-    Instruction *getSuccessor(void) { return successor; }
-    const Instruction *getSuccessor(void) const { return successor; }
+    Instruction *getSuccessor(bool stayInBlock = true);
+    const Instruction *getSuccessor(bool stayInBlock = true) const;
     void setSuccessor(Instruction *insn) { this->successor = insn; }
     /*! Get / set the parent basic block */
     BasicBlock *getParent(void) { return parent; }