From d71b2c2131767ccdce44b6cc555d041ff9354651 Mon Sep 17 00:00:00 2001 From: Luo Xionghu Date: Mon, 15 Sep 2014 08:23:38 +0800 Subject: add handleSelfLoopNode to insert while instruction on Gen IR level. v2: disable loop optimization by default due to still buggy. Signed-off-by: Luo Xionghu Signed-off-by: Zhigang Gong --- backend/src/backend/gen_encoder.cpp | 2 +- backend/src/ir/function.hpp | 3 +++ backend/src/ir/structural_analysis.cpp | 41 +++++++++++++++++++++++++++------- backend/src/ir/structural_analysis.hpp | 4 ++-- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp index 26e997d..c67e85e 100644 --- a/backend/src/backend/gen_encoder.cpp +++ b/backend/src/backend/gen_encoder.cpp @@ -1044,7 +1044,7 @@ namespace gbe this->setSrc1(&insn, GenRegister::immd(jumpDistance)); return; } - else if (insn.header.opcode == GEN_OPCODE_JMPI) { + else if (insn.header.opcode == GEN_OPCODE_JMPI){ jumpDistance = jumpDistance - 2; } else if(insn.header.opcode == GEN_OPCODE_ENDIF) diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp index a9cf22c..662781c 100644 --- a/backend/src/ir/function.hpp +++ b/backend/src/ir/function.hpp @@ -142,6 +142,9 @@ namespace ir { * else node into all the basic blocks belong to 'then' part while the liveout is * calculated in structural_analysis.cpp:calculateNecessaryLiveout(); */ std::set liveout; + /* selfLoop's label. + * */ + LabelIndex whileLabel; private: friend class Function; //!< Owns the basic blocks BlockSet predecessors; //!< Incoming blocks diff --git a/backend/src/ir/structural_analysis.cpp b/backend/src/ir/structural_analysis.cpp index 6d68602..1860ee9 100644 --- a/backend/src/ir/structural_analysis.cpp +++ b/backend/src/ir/structural_analysis.cpp @@ -57,6 +57,23 @@ namespace analysis iter++; } } + void ControlTree::handleSelfLoopNode(Node *loopnode, ir::LabelIndex& whileLabel) + { + ir::BasicBlock *pbb = loopnode->getExit(); + ir::BranchInstruction* pinsn = static_cast(pbb->getLastInstruction()); + ir::Register reg = pinsn->getPredicateIndex(); + ir::BasicBlock::iterator it = pbb->end(); + it--; + /* since this node is an while node, so we remove the BRA instruction at the bottom of the exit BB of 'node', + * and insert WHILE instead + */ + pbb->erase(it); + whileLabel = pinsn->getLabelIndex(); + ir::Instruction insn = ir::WHILE(whileLabel, reg); + ir::Instruction* p_new_insn = pbb->getParent().newInstruction(insn); + pbb->append(*p_new_insn); + pbb->whileLabel = whileLabel; + } /* recursive mark the bbs' variable needEndif, the bbs all belong to node.*/ void ControlTree::markNeedIf(Node *node, bool status) @@ -207,7 +224,7 @@ namespace analysis * structures */ while(rit != nodes.rend()) { - if((*rit)->type() == IfThen || (*rit)->type() == IfElse) + if((*rit)->type() == IfThen || (*rit)->type() == IfElse|| (*rit)->type() == SelfLoop) { if(false == (*rit)->mark && (*rit)->canBeHandled) { @@ -256,12 +273,12 @@ namespace analysis */ while(rit != nodes.rend()) { - if(((*rit)->type() == IfThen || (*rit)->type() == IfElse || (*rit)->type() == Block) && + if(((*rit)->type() == IfThen || (*rit)->type() == IfElse || (*rit)->type() == Block ||(*rit)->type() == SelfLoop) && (*rit)->canBeHandled && (*rit)->mark == true) { markStructuredNodes(*rit, false); std::set ns = getStructureBasicBlocksIndex(*rit, bbs); - ir::BasicBlock *entry = (*it)->getEntry(); + ir::BasicBlock *entry = (*rit)->getEntry(); int entryIndex = *(ns.begin()); for(size_t i=0; ichildren.begin(); + ir::LabelIndex whilelabel; + handleSelfLoopNode(*child_iter, whilelabel); + } + break; + default: break; } @@ -835,7 +860,6 @@ namespace analysis * ignore the identification of cyclic regions. */ Node * ControlTree::cyclicRegionType(Node *node, NodeList &nset) { -#if 0 /* check for self-loop */ if(nset.size() == 1) { @@ -875,7 +899,6 @@ namespace analysis return insertNode(p); } } -#endif return NULL; } @@ -998,9 +1021,9 @@ namespace analysis if(nset.find(entry) != nset.end()) entry = region; } + // FIXME loop optimization is still buggy and under development, now disable it by default. else { - /* We now only deal with acyclic regions at this moment. */ #if 0 reachUnder.clear(); nset.clear(); @@ -1027,9 +1050,11 @@ namespace analysis } else { -#endif post_ctr++; - // } + } +#else + post_ctr++; +#endif } } diff --git a/backend/src/ir/structural_analysis.hpp b/backend/src/ir/structural_analysis.hpp index 03df39e..dc2f3c2 100644 --- a/backend/src/ir/structural_analysis.hpp +++ b/backend/src/ir/structural_analysis.hpp @@ -191,7 +191,6 @@ namespace analysis } }; -#if 0 /* Self loop structure node */ class SelfLoopNode : public Node { @@ -259,7 +258,6 @@ namespace analysis return NULL; } }; -#endif /* computes the control tree, and do the structure identification during the computation */ class ControlTree @@ -308,6 +306,8 @@ namespace analysis bool pathBack(Node*, Node*); /* check if there is a barrier in a basic block */ bool checkForBarrier(const ir::BasicBlock*); + /* insert while instruction at the proper position of Node */ + void handleSelfLoopNode(Node *, ir::LabelIndex&); /* mark all the BasicBlockNodes of the control tree node n as status */ void markStructuredNodes(Node *n, bool status); /* mark all the ir::BasicBlocks' needEndIf of n as status */ -- cgit v1.2.3