Added support for lowering of return instruction
authorBenjamin Segovia <segovia.benjamin@gmail.com>
Mon, 14 May 2012 18:24:59 +0000 (18:24 +0000)
committerKeith Packard <keithp@keithp.com>
Fri, 10 Aug 2012 23:17:32 +0000 (16:17 -0700)
backend/src/CMakeLists.txt
backend/src/ir/context.cpp
backend/src/ir/context.hpp
backend/src/ir/function.cpp
backend/src/ir/function.hpp
backend/src/ir/instruction.cpp
backend/src/ir/instruction.hpp

index b88253c..c6c71d2 100644 (file)
@@ -71,6 +71,8 @@ else (GBE_USE_BLOB)
     ir/function.hpp
     ir/value.cpp
     ir/value.hpp
+    ir/lowering.cpp
+    ir/lowering.hpp
     backend/context.cpp
     backend/context.hpp
     backend/program.cpp
index e623bf7..61cfee0 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include "ir/context.hpp"
 #include "ir/unit.hpp"
+#include "ir/lowering.hpp"
 
 namespace gbe {
 namespace ir {
@@ -51,9 +52,15 @@ 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");
+    GBE_DELETE(usedLabels);
+
+    // Remove all returns and insert one unique return block at the end of the
+    // function
+    lowerReturn(unit, fn->getName());
+
+    // Properly order labels and compute the CFG
     fn->sortLabels();
     fn->computeCFG();
-    GBE_DELETE(usedLabels);
     const StackElem elem = fnStack.back();
     fnStack.pop_back();
     fn = elem.fn;
index 95920ec..ce3d782 100644 (file)
@@ -94,7 +94,7 @@ namespace ir {
       return fn->file.appendArrayTuple(reg, regNum);
     }
     /*! We just use variadic templates to forward instruction functions */
-#define DECL_INSN(NAME, FAMILY)                                 \
+#define DECL_INSN(NAME, FAMILY) \
     template <typename... Args> INLINE void NAME(Args...args);
 #include "ir/instruction.hxx"
 #undef DECL_INSN
@@ -103,15 +103,15 @@ namespace ir {
       return unit.getPointerSize();
     }
 
-#define DECL_THREE_SRC_INSN(NAME)                         \
-    INLINE void NAME(Type type,                           \
-                     Register dst,                        \
-                     Register src0,                       \
-                     Register src1,                       \
-                     Register src2)                       \
-    {                                                     \
-      const Tuple index = this->tuple(src0, src1, src2);  \
-      return this->NAME(type, dst, index);                \
+#define DECL_THREE_SRC_INSN(NAME) \
+    INLINE void NAME(Type type, \
+                     Register dst, \
+                     Register src0, \
+                     Register src1, \
+                     Register src2) \
+    { \
+      const Tuple index = this->tuple(src0, src1, src2); \
+      return this->NAME(type, dst, index); \
     }
     DECL_THREE_SRC_INSN(MAD);
     DECL_THREE_SRC_INSN(SEL);
@@ -137,7 +137,7 @@ namespace ir {
       this->STORE(type, index, offset, space, valueNum, dwAligned);
     }
 
-  private:
+  protected:
     /*! A block must be started with a label */
     void startBlock(void);
     /*! A block must be ended with a branch */
@@ -164,12 +164,12 @@ namespace ir {
   };
 
   // Use argument checker to assert argument value correctness
-#define DECL_INSN(NAME, FAMILY)                                   \
-  template <typename... Args>                                     \
-  INLINE void Context::NAME(Args...args) {                        \
-    GBE_ASSERTM(fn != NULL, "No function currently defined");     \
-    const Instruction insn = gbe::ir::NAME(args...);              \
-    this->append(insn);                                           \
+#define DECL_INSN(NAME, FAMILY) \
+  template <typename... Args> \
+  INLINE void Context::NAME(Args...args) { \
+    GBE_ASSERTM(fn != NULL, "No function currently defined"); \
+    const Instruction insn = gbe::ir::NAME(args...); \
+    this->append(insn); \
   }
 #include "ir/instruction.hxx"
 #undef DECL_INSN
index bf27f6f..cd63027 100644 (file)
@@ -47,14 +47,17 @@ namespace ir {
       if (insn.getOpcode() != OP_LABEL) return;
 
       // Create the new label
+#if 0
       Instruction *newLabel = newInstruction();
       *newLabel = LABEL(LabelIndex(last));
-
+#else
+      const Instruction newLabel = LABEL(LabelIndex(last));
+#endif
       // Replace the previous label instruction
       LabelInstruction &label = cast<LabelInstruction>(insn);
       const LabelIndex index = label.getLabelIndex();
       labelMap.insert(std::make_pair(index, LabelIndex(last++)));
-      newLabel->replace(&insn);
+      newLabel.replace(&insn);
     });
 
     // Patch all branch instructions with the new labels
@@ -67,12 +70,13 @@ namespace ir {
       const LabelIndex newIndex = labelMap.find(index)->second;
 
       // Insert the patched branch instruction
-      Instruction *newBra = newInstruction();
-      if (bra.isPredicated() == true)
-        *newBra = BRA(newIndex, bra.getPredicateIndex());
-      else
-        *newBra = BRA(newIndex);
-      newBra->replace(&insn);
+      if (bra.isPredicated() == true) {
+        const Instruction newBra = BRA(newIndex, bra.getPredicateIndex());
+        newBra.replace(&insn);
+      } else {
+        const Instruction newBra = BRA(newIndex);
+        newBra.replace(&insn);
+      }
     });
 
     // Reset the label to block mapping
index a2243d2..aefe96e 100644 (file)
@@ -207,9 +207,21 @@ namespace ir {
     }
     /*! Get function the entry point block */
     INLINE const BasicBlock &getTopBlock(void) const {
-     GBE_ASSERT(blockNum() > 0);
+      GBE_ASSERT(blockNum() > 0 && blocks[0] != NULL);
       return *blocks[0];
     }
+    /*! Get the last block */
+    INLINE const BasicBlock &getBottomBlock(void) const {
+      const uint32_t n = blockNum();
+      GBE_ASSERT(n > 0 && blocks[n-1] != NULL);
+      return *blocks[n-1];
+    }
+    /*! Get the last block */
+    INLINE BasicBlock &getBottomBlock(void) {
+      const uint32_t n = blockNum();
+      GBE_ASSERT(n > 0 && blocks[n-1] != NULL);
+      return *blocks[n-1];
+    }
     /*! Get block from its label */
     INLINE const BasicBlock &getBlock(LabelIndex label) const {
       GBE_ASSERT(label < labelNum() && labels[label] != NULL);
index ea5dd8c..176bf53 100644 (file)
@@ -778,7 +778,7 @@ namespace ir {
       out << "." << type << "." << addrSpace << (dwAligned ? "." : ".un") << "aligned";
       out << " {";
       for (uint32_t i = 0; i < valueNum; ++i)
-        out << "%" << this->getDst(fn, i) << (i != (valueNum-1) ? " " : "");
+        out << "%" << this->getDst(fn, i) << (i != (valueNum-1u) ? " " : "");
       out << "}";
       out << " %" << this->getSrc(fn, 0);
     }
@@ -788,7 +788,7 @@ namespace ir {
       out << "." << type << "." << addrSpace << (dwAligned ? "." : ".un") << "aligned";
       out << " %" << this->getSrc(fn, 0) << " {";
       for (uint32_t i = 0; i < valueNum; ++i)
-        out << "%" << this->getSrc(fn, i+1) << (i != (valueNum-1) ? " " : "");
+        out << "%" << this->getSrc(fn, i+1) << (i != (valueNum-1u) ? " " : "");
       out << "}";
     }
 
@@ -988,16 +988,18 @@ END_FUNCTION(Instruction, Register)
     return bb->getParent();
   }
 
-  void Instruction::replace(Instruction *other) {
+  void Instruction::replace(Instruction *other) const {
     Function &fn = other->getFunction();
     BasicBlock *bb = other->getParent();
-    if (bb->getFirstInstruction() == other) bb->setFirstInstruction(this);
-    if (bb->getLastInstruction() == other) bb->setLastInstruction(this);
-    if (other->predecessor) other->predecessor->successor = this;
-    if (other->successor) other->successor->predecessor = this;
-    this->parent = other->parent;
-    this->predecessor = other->predecessor;
-    this->successor = other->successor;
+    Instruction *insn = fn.newInstruction();
+    *insn = *this;
+    if (bb->getFirstInstruction() == other) bb->setFirstInstruction(insn);
+    if (bb->getLastInstruction() == other) bb->setLastInstruction(insn);
+    if (other->predecessor) other->predecessor->successor = insn;
+    if (other->successor) other->successor->predecessor = insn;
+    insn->parent = other->parent;
+    insn->predecessor = other->predecessor;
+    insn->successor = other->successor;
     fn.deleteInstruction(other);
   }
 
index d54f152..12cc126 100644 (file)
@@ -116,7 +116,7 @@ namespace ir {
      */
     bool wellFormed(std::string &why) const;
     /*! Replace other by this instruction */
-    void replace(Instruction *other);
+    void replace(Instruction *other) const;
     /*! Indicates if the instruction belongs to instruction type T. Typically, T
      *  can be BinaryInstruction, UnaryInstruction, LoadInstruction and so on
      */