summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@intel.com>2015-05-19 10:36:03 +0800
committerZhigang Gong <zhigang.gong@intel.com>2015-05-19 10:37:25 +0800
commit25fe857740b2ab6591e316c256afb51d3c3d4dc5 (patch)
tree3c13df3cb6fac3172873f5a32b6a38d6e22713b7
parent6aae2e8000b421f390b19404486a75b005720f12 (diff)
Remove some LGPL incompatible code.
Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
-rw-r--r--backend/src/CMakeLists.txt2
-rw-r--r--backend/src/ir/structural_analysis.cpp1092
-rw-r--r--backend/src/ir/structural_analysis.hpp342
-rw-r--r--backend/src/llvm/llvm_to_gen.cpp13
4 files changed, 0 insertions, 1449 deletions
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index ddf295df..8f574d49 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -66,8 +66,6 @@ set (GBE_SRC
ir/lowering.hpp
ir/printf.cpp
ir/printf.hpp
- ir/structural_analysis.cpp
- ir/structural_analysis.hpp
ir/immediate.hpp
ir/immediate.cpp
backend/context.cpp
diff --git a/backend/src/ir/structural_analysis.cpp b/backend/src/ir/structural_analysis.cpp
deleted file mode 100644
index 101570a3..00000000
--- a/backend/src/ir/structural_analysis.cpp
+++ /dev/null
@@ -1,1092 +0,0 @@
-/*
- * structural_analysis.hpp
- * This code is derived from the ControlTree.h and ControlTree.cpp of
- * project gpuocelot by Yongjia Zhang.
- * The original copyright of gpuocelot appears below in its entirety.
- */
-
-/*
- * Copyright 2011
- * GEORGIA TECH RESEARCH CORPORATION
- * ALL RIGHTS RESERVED
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimers.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimers in the
- * documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of GEORGIA TECH RESEARCH CORPORATION nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH RESEARCH
- * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You agree that the Software will not be shipped, transferred, exported,
- * or re-exported directly into any country prohibited by the United States
- * Export Administration Act and the regulations thereunder nor will be
- * used for any purpose prohibited by the Act.
- */
-
-
-#include "structural_analysis.hpp"
-
-namespace analysis
-{
- ControlTree::~ControlTree()
- {
- NodeVector::iterator iter = nodes.begin();
- NodeVector::iterator iter_end = nodes.end();
- while(iter != iter_end)
- {
- delete *iter;
- iter++;
- }
- }
- void ControlTree::handleSelfLoopNode(Node *loopnode, ir::LabelIndex& whileLabel)
- {
- //NodeList::iterator child_iter = (*it)->children.begin();
- ir::BasicBlock *pbb = loopnode->getExit();
- GBE_ASSERT(pbb->isLoopExit);
- ir::BasicBlock::iterator it = pbb->end();
- it--;
- if (pbb->hasExtraBra)
- it--;
- ir::BranchInstruction* pinsn = static_cast<ir::BranchInstruction *>(&*it);
-
- if(!pinsn->isPredicated()){
- std::cout << "WARNING:" << "endless loop detected!" << std::endl;
- return;
- }
- ir::Register reg = pinsn->getPredicateIndex();
- /* 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
- */
- whileLabel = pinsn->getLabelIndex();
- ir::Instruction insn = ir::WHILE(whileLabel, reg);
- ir::Instruction* p_new_insn = pbb->getParent().newInstruction(insn);
- pbb->insertAt(it, *p_new_insn);
- pbb->whileLabel = whileLabel;
- pbb->erase(it);
- }
-
- /* recursive mark the bbs' variable needEndif, the bbs all belong to node.*/
- void ControlTree::markNeedIf(Node *node, bool status)
- {
- if(node->type() == BasicBlock)
- {
- ir::BasicBlock* bb = ((BasicBlockNode*)node)->getBasicBlock();
- bb->needIf = status;
- return;
- }
- NodeList::iterator it = node->children.begin();
- while(it != node->children.end())
- {
- markNeedIf(*it,status);
- it++;
- }
- }
-
- /* recursive mark the bbs' variable needIf, the bbs all belong to node.*/
- void ControlTree::markNeedEndif(Node *node, bool status)
- {
- if(node->type() == BasicBlock)
- {
- ir::BasicBlock* bb = ((BasicBlockNode*)node)->getBasicBlock();
- bb->needEndif = status;
- return;
- }
-
- NodeList::iterator it = node->children.begin();
- while(it != node->children.end())
- {
- markNeedEndif(*it, status);
- it++;
- }
- }
-
- /* recursive mark the bbs' variable mark, the bbs all belong to node. */
- void ControlTree::markStructuredNodes(Node *node, bool status)
- {
- if(node->type() == BasicBlock)
- {
- BasicBlockNode* pbb = static_cast<BasicBlockNode *>(node);
- pbb->getBasicBlock()->belongToStructure = true;
- }
- node->mark = status;
- NodeList::iterator it = node->children.begin();
- while(it != node->children.end())
- {
- markStructuredNodes(*it, status);
- it++;
- }
- }
-
- void ControlTree::handleIfNode(Node *node, ir::LabelIndex& matchingEndifLabel, ir::LabelIndex& matchingElseLabel)
- {
- ir::BasicBlock *pbb = node->getExit();
- ir::BranchInstruction* pinsn = static_cast<ir::BranchInstruction *>(pbb->getLastInstruction());
- ir::Register reg = pinsn->getPredicateIndex();
- ir::BasicBlock::iterator it = pbb->end();
- it--;
- /* since this node is an if node, so we remove the BRA instruction at the bottom of the exit BB of 'node',
- * and insert IF instead
- */
- pbb->erase(it);
- ir::Instruction insn = ir::IF(matchingElseLabel, reg, node->inversePredicate);
- ir::Instruction* p_new_insn = pbb->getParent().newInstruction(insn);
- pbb->append(*p_new_insn);
- pbb->matchingEndifLabel = matchingEndifLabel;
- pbb->matchingElseLabel = matchingElseLabel;
- }
-
- void ControlTree::handleThenNode(Node *node, ir::LabelIndex& endiflabel)
- {
- ir::BasicBlock *pbb = node->getExit();
- ir::BasicBlock::iterator it = pbb->end();
- it--;
- ir::Instruction *p_last_insn = pbb->getLastInstruction();
-
- endiflabel = fn->newLabel();
- //pbb->thisEndifLabel = endiflabel;
-
- ir::Instruction insn = ir::ENDIF(endiflabel);
- ir::Instruction* p_new_insn = pbb->getParent().newInstruction(insn);
- // we need to insert ENDIF before the BRA(if exists).
- bool append_bra = false;
- if((*it).getOpcode() == ir::OP_BRA)
- {
- pbb->erase(it);
- append_bra = true;
- }
- pbb->append(*p_new_insn);
- if(append_bra)
- pbb->append(*p_last_insn);
- }
-
-
- void ControlTree::handleThenNode2(Node *node, Node *elsenode, ir::LabelIndex elseBBLabel)
- {
- ir::BasicBlock *pbb = node->getExit();
- ir::BasicBlock::iterator it = pbb->end();
- it--;
- if((*it).getOpcode() == ir::OP_BRA)
- pbb->erase(it);
-
- if(node->getExit()->getNextBlock() == elsenode->getEntry())
- return;
-
- // Add an unconditional jump to 'else' block
- ir::Instruction insn = ir::BRA(elseBBLabel);
- ir::Instruction* p_new_insn = pbb->getParent().newInstruction(insn);
- pbb->append(*p_new_insn);
- }
-
-
- void ControlTree::handleElseNode(Node* node, ir::LabelIndex& elselabel, ir::LabelIndex& endiflabel)
- {
- // to insert ENDIF properly
- handleThenNode(node, endiflabel);
-
- ir::BasicBlock *pbb = node->getEntry();
- ir::BasicBlock::iterator it = pbb->begin();
- it++;
-
- elselabel = fn->newLabel();
- pbb->thisElseLabel = elselabel;
-
- // insert ELSE properly
- ir::Instruction insn = ir::ELSE(endiflabel);
- ir::Instruction* p_new_insn = pbb->getParent().newInstruction(insn);
-
- pbb->insertAt(it, *p_new_insn);
- }
-
-
- void ControlTree::handleStructuredNodes()
- {
- NodeVector::iterator it;
- NodeVector::iterator end = nodes.end();
- NodeVector::iterator begin = nodes.begin();
- it = end;
- it--;
- NodeVector::reverse_iterator rit = nodes.rbegin();
- /* structured bbs only need if and endif insn to handle the execution
- * in structure entry and exit BasicBlock, so we process the nodes backward, since
- * the node at the back of nodes is always a 'not smaller' structure then
- * the ones before it. we mark the nodes which are sub-nodes of the node
- * we are dealing with, in order to ensure we are always handling the 'biggest'
- * structures */
- while(rit != nodes.rend())
- {
- if((*rit)->type() == IfThen || (*rit)->type() == IfElse|| (*rit)->type() == SelfLoop)
- {
- if(false == (*rit)->mark && (*rit)->canBeHandled)
- {
- markStructuredNodes(*rit, true);
- /* only the entry bb of this structure needs 'if' at backend and
- * only the exit bb of this structure needs 'endif' at backend
- * see comment about needEndif and needIf at function.hpp for detail. */
- markNeedEndif(*rit, false);
- markNeedIf(*rit, false);
- ir::BasicBlock* entry = (*rit)->getEntry();
- ir::BasicBlock* eexit = (*rit)->getExit();
- entry->needIf = true;
- eexit->needEndif = true;
- entry->endifLabel = fn->newLabel();
- eexit->endifLabel = entry->endifLabel;
- eexit->isStructureExit = true;
- eexit->matchingStructureEntry = entry;
- }
- }
- rit++;
- }
-
- rit = nodes.rbegin();
- gbe::vector<ir::BasicBlock *> &blocks = fn->getBlocks();
- std::vector<ir::BasicBlock *> bbs;
- bbs.resize(blocks.size());
-
- /* here insert the bras to the BBs, which would
- * simplify the reorder of basic blocks */
- for(size_t i = 0; i < blocks.size(); ++i)
- {
- bbs[i] = blocks[i];
- if(i != blocks.size() -1 &&
- (bbs[i]->getLastInstruction()->getOpcode() != ir::OP_BRA ||
- (bbs[i]->isStructureExit && bbs[i]->isLoopExit)))
- {
- ir::Instruction insn = ir::BRA(bbs[i]->getNextBlock()->getLabelIndex());
- ir::Instruction* pNewInsn = bbs[i]->getParent().newInstruction(insn);
- bbs[i]->append(*pNewInsn);
- if (bbs[i]->isStructureExit && bbs[i]->isLoopExit)
- bbs[i]->hasExtraBra = true;
- }
- }
-
- /* now, reorder the basic blocks to reduce the unconditional jump we inserted whose
- * targets are the 'else' nodes. the algorithm is quite simple, just put the unstructured
- * BBs(maybe belong to another structure, but not this one) in front of the entry BB of
- * this structure in front of all the others and put the other unstructured BBs at the
- * back of the others. the sequence of structured is get through function getStructureSequence.
- */
- while(rit != nodes.rend())
- {
- if(((*rit)->type() == IfThen || (*rit)->type() == IfElse || (*rit)->type() == Block ||(*rit)->type() == SelfLoop) &&
- (*rit)->canBeHandled && (*rit)->mark == true)
- {
- markStructuredNodes(*rit, false);
- std::set<int> ns = getStructureBasicBlocksIndex(*rit, bbs);
- ir::BasicBlock *entry = (*rit)->getEntry();
-
- int entryIndex = *(ns.begin());
- for(size_t i=0; i<bbs.size(); ++i)
- {
- if(bbs[i] == entry)
- entryIndex = i;
- }
-
- std::set<int>::iterator iter = ns.begin();
- int index = *iter;
-
- std::vector<ir::BasicBlock *> unstruSeqHead;
- std::vector<ir::BasicBlock *> unstruSeqTail;
-
- iter = ns.begin();
- while(iter != ns.end())
- {
- if(index != *iter)
- {
- if(index < entryIndex)
- unstruSeqHead.push_back(bbs[index]);
- else
- unstruSeqTail.push_back(bbs[index]);
- index++;
- }
- else
- {
- index++;
- iter++;
- }
- }
-
- std::vector<ir::BasicBlock *> struSeq;
- getStructureSequence(*rit, struSeq);
-
- int firstindex = *(ns.begin());
- for(size_t i = 0; i < unstruSeqHead.size(); ++i)
- bbs[firstindex++] = unstruSeqHead[i];
- for(size_t i = 0; i < struSeq.size(); ++i)
- bbs[firstindex++] = struSeq[i];
- for(size_t i = 0; i < unstruSeqTail.size(); ++i)
- bbs[firstindex++] = unstruSeqTail[i];
- }
- rit++;
- }
-
- /* now, erase the BRAs inserted before whose targets are their fallthrough blocks */
- for(size_t i=0; i<bbs.size(); ++i)
- {
- if(bbs[i]->getLastInstruction()->getOpcode() == ir::OP_BRA &&
- !((ir::BranchInstruction*)(bbs[i]->getLastInstruction()))->isPredicated())
- {
- if(((ir::BranchInstruction *)bbs[i]->getLastInstruction())->getLabelIndex() == bbs[i+1]->getLabelIndex())
- {
- ir::BasicBlock::iterator it= bbs[i]->end();
- it--;
-
- bbs[i]->erase(it);
-
- if (bbs[i]->hasExtraBra)
- bbs[i]->hasExtraBra = false;
- }
- }
- }
- for(size_t i=0; i<bbs.size(); ++i)
- blocks[i] = bbs[i];
-
- fn->sortLabels();
- fn->computeCFG();
-
- it = begin;
- while(it != end)
- {
- if((*it)->canBeHandled)
- {
- switch((*it)->type())
- {
- case IfThen:
- {
- NodeList::iterator child_iter = (*it)->children.end();
- ir::LabelIndex endiflabel;
- child_iter--;
- handleThenNode(*child_iter, endiflabel); // this call would pass out the proper endiflabel for handleIfNode's use.
- child_iter--;
- handleIfNode(*child_iter, endiflabel, endiflabel);
- }
- break;
-
- case IfElse:
- {
- NodeList::iterator child_iter = (*it)->children.end();
- ir::LabelIndex endiflabel;
- ir::LabelIndex elselabel;
- NodeList::iterator else_node;
- child_iter--;
- else_node = child_iter;
- handleElseNode(*child_iter, elselabel, endiflabel);
- ir::LabelIndex elseBBLabel = (*child_iter)->getEntry()->getLabelIndex();
- child_iter--;
- handleThenNode2(*child_iter, *else_node, elseBBLabel);
- child_iter--;
- handleIfNode(*child_iter, endiflabel, elselabel);
- }
- break;
-
- case SelfLoop:
- {
- ir::LabelIndex whilelabel;
- handleSelfLoopNode(*it, whilelabel);
- }
- break;
-
- default:
- break;
- }
- }
-
- it++;
- }
-
- }
-
- void ControlTree::getStructureSequence(Node *node, std::vector<ir::BasicBlock*> &seq)
- {
- /* in the control tree, for if-then, if node is before then node; for if-else, the
- * stored sequence is if-then-else, for block structure, the stored sequence is just
- * their executed sequence. so we could just get the structure sequence by recrusive
- * calls getStructureSequence to all the elements in children one by one.
- */
- if(node->type() == BasicBlock)
- {
- seq.push_back(((BasicBlockNode *)node)->getBasicBlock());
- return;
- }
-
- NodeList::iterator iter = node->children.begin();
- while(iter != node->children.end())
- {
- getStructureSequence(*iter, seq);
- iter++;
- }
-
- }
-
-
- std::set<int> ControlTree::getStructureBasicBlocksIndex(Node* node, std::vector<ir::BasicBlock *> &bbs)
- {
- std::set<int> result;
- if(node->type() == BasicBlock)
- {
- for(size_t i=0; i<bbs.size(); i++)
- {
- if(bbs[i] == ((BasicBlockNode *)node)->getBasicBlock())
- {
- result.insert(i);
- break;
- }
- }
- return result;
- }
- NodeList::iterator iter = (node->children).begin();
- NodeList::iterator end = (node->children).end();
- while(iter != end)
- {
- std::set<int> ret = getStructureBasicBlocksIndex(*iter, bbs);
- result.insert(ret.begin(), ret.end());
- iter++;
- }
- return result;
- }
-
-
- std::set<ir::BasicBlock *> ControlTree::getStructureBasicBlocks(Node *node)
- {
- std::set<ir::BasicBlock *> result;
- if(node->type() == BasicBlock)
- {
- result.insert(((BasicBlockNode *)node)->getBasicBlock());
- return result;
- }
- NodeList::iterator iter = (node->children).begin();
- NodeList::iterator end = (node->children).end();
- while(iter != end)
- {
- std::set<ir::BasicBlock *> ret = getStructureBasicBlocks(*iter);
- result.insert(ret.begin(), ret.end());
- iter++;
- }
- return result;
- }
-
-
- Node* ControlTree::insertNode(Node *p_node)
- {
- nodes.push_back(p_node);
- return p_node;
- }
-
-
- bool ControlTree::checkForBarrier(const ir::BasicBlock* bb)
- {
- ir::BasicBlock::const_iterator iter = bb->begin();
- ir::BasicBlock::const_iterator iter_end = bb->end();
- while(iter != iter_end)
- {
- if((*iter).getOpcode() == ir::OP_SYNC)
- return true;
- iter++;
- }
-
- return false;
- }
-
-
- void ControlTree::getLiveIn(ir::BasicBlock& bb, std::set<ir::Register>& livein)
- {
- ir::BasicBlock::iterator iter = bb.begin();
- std::set<ir::Register> varKill;
- while(iter != bb.end())
- {
- ir::Instruction& insn = *iter;
- const uint32_t srcNum = insn.getSrcNum();
- const uint32_t dstNum = insn.getDstNum();
- for(uint32_t srcID = 0; srcID < srcNum; ++srcID)
- {
- const ir::Register reg = insn.getSrc(srcID);
- if(varKill.find(reg) == varKill.end())
- livein.insert(reg);
- }
- for(uint32_t dstID = 0; dstID < dstNum; ++dstID)
- {
- const ir::Register reg = insn.getDst(dstID);
- varKill.insert(reg);
- }
-
- iter++;
- }
- }
-
- void ControlTree::calculateNecessaryLiveout()
- {
- NodeVector::iterator iter = nodes.begin();
-
- while(iter != nodes.end())
- {
- switch((*iter)->type())
- {
- case IfElse:
- {
- std::set<ir::BasicBlock *> bbs;
- NodeList::iterator thenIter = (*iter)->children.begin();
- thenIter++;
- bbs = getStructureBasicBlocks(*thenIter);
-
- Node *elseNode = *((*iter)->children.rbegin());
- std::set<ir::Register> livein;
- getLiveIn(*(elseNode->getEntry()), livein);
-
- std::set<ir::BasicBlock *>::iterator bbiter = bbs.begin();
- while(bbiter != bbs.end())
- {
- (*bbiter)->liveout.insert(livein.begin(), livein.end());
- bbiter++;
- }
- }
-
- default:
- break;
- }
- iter++;
- }
- }
-
-
- void ControlTree::initializeNodes()
- {
- ir::BasicBlock& tmp_bb = fn->getTopBlock();
- ir::BasicBlock* p_tmp_bb = &tmp_bb;
- Node* p = NULL;
-
- if(NULL != p_tmp_bb)
- {
- Node *p_tmp_node = new BasicBlockNode(p_tmp_bb);
- p_tmp_node->label = p_tmp_bb->getLabelIndex();
-
- if(checkForBarrier(p_tmp_bb))
- p_tmp_node->hasBarrier() = true;
-
- nodes.push_back(p_tmp_node);
- bbmap[p_tmp_bb] = p_tmp_node;
- p_tmp_bb = p_tmp_bb->getNextBlock();
- p = p_tmp_node;
- }
-
- while(p_tmp_bb != NULL)
- {
- Node *p_tmp_node = new BasicBlockNode(p_tmp_bb);
- p_tmp_node->label = p_tmp_bb->getLabelIndex();
-
- if(checkForBarrier(p_tmp_bb))
- p_tmp_node->hasBarrier() = true;
-
- p->fallthrough() = p_tmp_node;
- p = p_tmp_node;
- nodes.push_back(p_tmp_node);
- bbmap[p_tmp_bb] = p_tmp_node;
- p_tmp_bb = p_tmp_bb->getNextBlock();
- }
-
- if(NULL != p)
- p->fallthrough() = NULL;
-
- p_tmp_bb = &tmp_bb;
-
- this->nodes_entry = bbmap[p_tmp_bb];
-
- while(p_tmp_bb != NULL)
- {
- ir::BlockSet::const_iterator iter_begin = p_tmp_bb->getPredecessorSet().begin();
- ir::BlockSet::const_iterator iter_end = p_tmp_bb->getPredecessorSet().end();
- while(iter_begin != iter_end)
- {
- bbmap[p_tmp_bb]->preds().insert(bbmap[*iter_begin]);
- iter_begin++;
- }
-
- iter_begin = p_tmp_bb->getSuccessorSet().begin();
- iter_end = p_tmp_bb->getSuccessorSet().end();
- while(iter_begin != iter_end)
- {
- bbmap[p_tmp_bb]->succs().insert(bbmap[*iter_begin]);
- iter_begin++;
- }
-
- p_tmp_bb = p_tmp_bb->getNextBlock();
- }
- }
-
-
- void ControlTree::DFSPostOrder(Node *start)
- {
- visited.insert(start);
- NodeSet::iterator y;
- NodeSet::iterator iter_begin = start->succs().begin();
- NodeSet::iterator iter_end = start->succs().end();
- for(y = iter_begin; y != iter_end; ++y )
- {
- if(visited.find(*y) != visited.end())
- continue;
- DFSPostOrder(*y);
- }
- post_order.push_back(start);
- }
-
-
- bool ControlTree::isCyclic(Node* node)
- {
- if(node->type() == NaturalLoop ||
- node->type() == WhileLoop ||
- node->type() == SelfLoop)
- return true;
-
- return false;
- }
-
-
- bool ControlTree::isBackedge(const Node* head, const Node* tail)
- {
- const Node* match[] = {head, tail};
- NodeList::iterator n = find_first_of(post_order.begin(), post_order.end(), match, match + 2);
-
- if(*n == head)
- return true;
- if(*n == tail)
- return false;
-
- return false;
- }
-
-
- /* this algorithm is from Muchnick's textbook(sec 7.7) (Advanced Compiler Design and Implementation) */
- Node* ControlTree::acyclicRegionType(Node* node, NodeSet& nset)
- {
- nset.clear();
- Node *n;
- bool p, s, barrier;
- NodeList nodes;
-
- n = node;
- p = true;
- s = (n->succs().size()==1);
- barrier = n->hasBarrier();
- while(p && s && !barrier)
- {
- if(nset.insert(n).second)
- nodes.push_back(n);
- n = *(n->succs().begin());
- barrier = n->hasBarrier();
- p = (n->preds().size() == 1);
- s = (n->succs().size() == 1);
- }
-
- if(p && !barrier)
- {
- if(nset.insert(n).second)
- nodes.push_back(n);
- }
-
- n = node;
- p = (n->preds().size() == 1);
- s = true;
- barrier = n->hasBarrier();
-
- while(p && s && !barrier)
- {
- if(nset.insert(n).second)
- nodes.push_front(n);
- n = *(n->preds().begin());
- barrier = n->hasBarrier();
- p = (n->preds().size() == 1);
- s = (n->succs().size() == 1);
- }
-
- if(s && !barrier)
- {
- if(nset.insert(n).second)
- nodes.push_front(n);
- }
-
- node = n;
-
- if(nodes.size() >=2 )
- {
- Node* p = new BlockNode(nodes);
- NodeList::iterator iter = nodes.begin();
- while(iter != nodes.end())
- {
- if((*iter)->canBeHandled == false)
- {
- p->canBeHandled = false;
- break;
- }
- iter++;
- }
-
- return insertNode(p);
- }
-
- else if(node->succs().size() == 2)
- {
- Node *m;
- m = *(node->succs().begin());
- n = *(++(node->succs().begin()));
-
- /* check for if node then n */
- if( n->succs().size() == 1 &&
- n->preds().size() == 1 &&
- *(n->succs().begin()) == m &&
- !n->hasBarrier() && !node->hasBarrier())
- {
- nset.clear();
- nset.insert(node);
- nset.insert(n);
-
- Node* p = new IfThenNode(node, n);
- if(node->fallthrough() == m)
- node->inversePredicate = false;
-
- if(node->canBeHandled == false || n->canBeHandled == false)
- p->canBeHandled = false;
-
- return insertNode(p);
- }
-
- /* check for if node then m */
- if(m->succs().size() == 1 &&
- m->preds().size() == 1 &&
- *(m->succs().begin()) == n &&
- !m->hasBarrier() && !node->hasBarrier())
- {
- nset.clear();
- nset.insert(node);
- nset.insert(m);
-
- Node* p = new IfThenNode(node, m);
- if(node->fallthrough() == n)
- node->inversePredicate = false;
-
- if(node->canBeHandled == false || m->canBeHandled == false)
- p->canBeHandled = false;
-
- return insertNode(p);
- }
-
- /* check for if node then n else m */
- if(m->succs().size() == 1 && n->succs().size() == 1 &&
- m->preds().size() == 1 && n->preds().size() == 1 &&
- *(m->succs().begin()) == *(n->succs().begin()) &&
- node->fallthrough() == n && !m->hasBarrier() && !n->hasBarrier() && !node->hasBarrier())
- {
- nset.clear();
- nset.insert(node);
- nset.insert(n);
- nset.insert(m);
-
- Node* p = new IfElseNode(node, n, m);
-
- if(node->canBeHandled == false ||
- m->canBeHandled == false ||
- n->canBeHandled == false)
- p->canBeHandled = false;
-
- return insertNode(p);
- }
-
- /* check for if node then m else n */
- if(m->succs().size() == 1 && n->succs().size() == 1 &&
- m->preds().size() == 1 && n->preds().size() == 1 &&
- *(m->succs().begin()) == *(n->succs().begin()) &&
- node->fallthrough() == m && !m->hasBarrier() && !n->hasBarrier() &&!node->hasBarrier())
- {
- nset.clear();
- nset.insert(node);
- nset.insert(m);
- nset.insert(n);
-
- Node* p = new IfElseNode(node, m, n);
-
- if(node->canBeHandled == false ||
- m->canBeHandled == false ||
- n->canBeHandled == false)
- p->canBeHandled = false;
- return insertNode(p);
- }
- }
-
- return NULL;
- }
-
- bool ControlTree::path(Node *from, Node *to, Node *notthrough)
- {
-
- if(from == notthrough || visited.find(from) != visited.end())
- return false;
-
- if(from == to)
- return true;
-
- visited.insert(from);
-
- for(NodeSet::const_iterator s = from->succs().begin(); s != from->succs().end(); s++)
- {
- if(path(*s, to, notthrough))
- return true;
- }
-
- return false;
- }
-
-
- Node * ControlTree::cyclicRegionType(Node *node, NodeList &nset)
- {
- /* check for self-loop */
- if(nset.size() == 1)
- {
- if(node->succs().find(node) != node->succs().end())
- {
- Node* p = new SelfLoopNode(node);
-
- p->canBeHandled = true;
- node->getExit()->isLoopExit = true;
- return insertNode(p);
- }
- else
- return NULL;
- }
-
- //FIXME: as our IR could only handle self loop, the while loop node
- //is disabled to avoid performace regression by the path function.
-#if 0
- /* check for improper region */
- for(NodeList::const_iterator m = nset.begin(); m != nset.end(); m++)
- {
- visited.clear();
- if(!path(node, *m))
- return NULL;
- }
-
- /* check for while loop */
- NodeList::iterator m;
- for(m = nset.begin(); m != nset.end(); ++m)
- {
- if(*m == node)
- continue;
- if(node->succs().size() == 2 && (*m)->succs().size() == 1 &&
- node->preds().size() == 2 && (*m)->preds().size() == 1)
- {
- Node* p = new WhileLoopNode(node, *m);
-
- p->canBeHandled = false;
-
- return insertNode(p);
- }
- }
-#endif
-
- return NULL;
- }
-
-
- /* this algorithm is from Muchnick's textbook(sec 7.7) (Advanced Compiler Design and Implementation) */
- void ControlTree::reduce(Node* node, NodeSet nodeSet)
- {
- NodeSet::iterator n;
- for(n = nodeSet.begin(); n != nodeSet.end(); n++)
- {
- NodeSet::iterator p;
- for(p = (*n)->preds().begin(); p != (*n)->preds().end(); p++)
- {
- if(nodeSet.find(*p) != nodeSet.end())
- continue;
-
- (*p)->succs().erase(*n);
-
- (*p)->succs().insert(node);
- node->preds().insert(*p);
-
- if((*p)->fallthrough() == *n)
- (*p)->fallthrough() = node;
- }
-
-
- NodeSet::iterator s;
- for(s = (*n)->succs().begin(); s != (*n)->succs().end(); s++)
- {
- if(nodeSet.find(*s) != nodeSet.end())
- continue;
-
- (*s)->preds().erase(*n);
-
- (*s)->preds().insert(node);
- node->succs().insert(*s);
-
- if((*n)->fallthrough() == *s)
- node->fallthrough() = *s;
- }
- }
-
- if(!isCyclic(node))
- {
- for(n = nodeSet.begin(); n != nodeSet.end(); n++)
- {
- bool shouldbreak = false;
- NodeSet::iterator p;
- for(p = (*n)->preds().begin(); p != (*n)->preds().end(); p++)
- {
- if(nodeSet.find(*p) == nodeSet.end())
- continue;
-
- if(isBackedge(*p, *n))
- {
- node->preds().insert(node);
- node->succs().insert(node);
-
- shouldbreak = true;
- break;
- }
- }
-
- if(shouldbreak)
- break;
- }
- }
-
- compact(node, nodeSet);
- }
-
-
- /* this algorithm is from Muchnick's textbook(sec 7.7) (Advanced Compiler Design and Implementation) */
- void ControlTree::compact(Node* node, NodeSet nodeSet)
- {
- NodeList::iterator n, pos;
- for(n = post_order.begin(); n!= post_order.end() && !nodeSet.empty();)
- {
- if(!nodeSet.erase(*n))
- {
- n++;
- continue;
- }
-
- n = post_order.erase(n);
- pos = n;
- }
-
- post_ctr = post_order.insert(pos, node);
- }
-
-
- /* this algorithm is from Muchnick's textbook(sec 7.7) (Advanced Compiler Design and Implementation) */
- void ControlTree::structuralAnalysis(Node *entry)
- {
- Node* n;
- NodeSet nset;
- NodeList reachUnder;
- bool changed;
- do
- {
- changed = false;
- post_order.clear();
- visited.clear();
-
- DFSPostOrder(entry);
- post_ctr = post_order.begin();
-
- while(post_order.size() > 1 && post_ctr != post_order.end())
- {
- n = *post_ctr;
- Node* region = acyclicRegionType(n, nset);
-
- if( NULL != region)
- {
- changed = true;
-
- reduce(region, nset);
-
- if(nset.find(entry) != nset.end())
- entry = region;
- }
- else
- {
- reachUnder.clear();
- nset.clear();
-
- //reuse the loop info from llvm gaterLoopInfo.
- const gbe::vector<ir::Loop *> &loops = fn->getLoops();
- if(loops.size() == 0){
- post_ctr++;
- continue;
- }
-
- Node* loop_header = NULL;
- //if n is basic block node, query the llvm loop info to find the loop whoose loop header is n;
- if(n->type() == BasicBlock){
- for (auto l : loops) {
- ir::BasicBlock &a = fn->getBlock(l->bbs[0]);
- loop_header = bbmap.find(&a)->second;
-
- if(loop_header == n){
- for (auto bb : l->bbs) {
- ir::BasicBlock &tmp = fn->getBlock(bb);
- Node* node_ = bbmap.find(&tmp)->second;
- reachUnder.push_front(node_);
- nset.insert(node_);
- }
- break;
- }
- }
- }else{
- //n is compacted node, it would have a successor pointed to itself for self loop.
- if(n->succs().find(n) != n->succs().end())
- {
- reachUnder.push_front(n);
- nset.insert(n);
- }
- }
-
- region = cyclicRegionType(n, reachUnder);
-
- if(NULL != region)
- {
- reduce(region, nset);
- changed = true;
-
- if(nset.find(entry) != nset.end())
- entry = region;
- }
- else
- {
- post_ctr++;
- }
- }
- }
-
- if(!changed)
- break;
-
- } while(post_order.size()>1);
-
- }
-
- void ControlTree::analyze()
- {
- initializeNodes();
- structuralAnalysis(nodes_entry);
- handleStructuredNodes();
- calculateNecessaryLiveout();
- }
-}
diff --git a/backend/src/ir/structural_analysis.hpp b/backend/src/ir/structural_analysis.hpp
deleted file mode 100644
index 7aaa5334..00000000
--- a/backend/src/ir/structural_analysis.hpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * structural_analysis.hpp
- * This code is derived from the ControlTree.h and ControlTree.cpp of
- * project gpuocelot by Yongjia Zhang.
- * The original copyright of gpuocelot appears below in its entirety.
- */
-
-/*
- * Copyright 2011
- * GEORGIA TECH RESEARCH CORPORATION
- * ALL RIGHTS RESERVED
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimers.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimers in the
- * documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of GEORGIA TECH RESEARCH CORPORATION nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH RESEARCH
- * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You agree that the Software will not be shipped, transferred, exported,
- * or re-exported directly into any country prohibited by the United States
- * Export Administration Act and the regulations thereunder nor will be
- * used for any purpose prohibited by the Act.
- */
-
-
-#ifndef __STRUCTURAL_ANALYSIS_HPP__
-#define __STRUCTURAL_ANALYSIS_HPP__
-
-#include "ir/unit.hpp"
-#include "ir/function.hpp"
-#include "ir/instruction.hpp"
-
-#include <iostream>
-#include <unordered_set>
-#include <unordered_map>
-#include <vector>
-#include <map>
-#include <list>
-#include <algorithm>
-#include <set>
-#define TRANSFORM_UNSTRUCTURE
-
-namespace analysis
-{
- using namespace std;
- using namespace gbe;
-
- enum RegionType
- {
- BasicBlock = 0,
- Block,
- IfThen,
- IfElse,
- SelfLoop,
- WhileLoop,
- NaturalLoop
- } ;
-
- /* control tree virtual node */
- class Node;
-
- typedef unordered_set<Node *> NodeSet;
- typedef list<Node *> NodeList;
- typedef std::vector<Node *> NodeVector;
-
- /* control tree virtual node */
- class Node
- {
- public:
- Node(RegionType rtype, const NodeList& children): has_barrier(false), mark(false), canBeHandled(true), inversePredicate(true)
- {
- this->rtype = rtype;
- this->children = children;
- }
- virtual ~Node() {}
- NodeSet& preds() { return pred; }
- NodeSet& succs() { return succ; }
- Node*& fallthrough() { return fall_through; }
- bool& hasBarrier() { return has_barrier; }
- RegionType type() { return rtype; }
- virtual ir::BasicBlock* getEntry()
- {
- return (*(children.begin()))->getEntry();
- }
- virtual ir::BasicBlock* getExit()
- {
- return (*(children.rbegin()))->getExit();
- }
-
- public:
- RegionType rtype;
- NodeSet pred;
- NodeSet succ;
- NodeList children;
- Node* fall_through;
- bool has_barrier;
- bool mark;
- bool canBeHandled;
- //label is for debug
- int label;
- /* inversePredicate should be false under two circumstance,
- * fallthrough is the same with succs:
- * (1) n->succs == m && node->fallthrough == m
- * node
- * | \
- * | \
- * m<--n
- * (2) m->succs == n && node->fallthrough == n
- * node
- * | \
- * | \
- * m-->n
- * */
- bool inversePredicate;
- };
-
- /* represents basic block */
- class BasicBlockNode : public Node
- {
- public:
- BasicBlockNode(ir::BasicBlock *p_bb) : Node(BasicBlock, NodeList()) { this->p_bb = p_bb; }
- virtual ~BasicBlockNode() {}
- ir::BasicBlock* getBasicBlock() { return p_bb; }
- virtual ir::BasicBlock* getEntry() { return p_bb; }
- virtual ir::BasicBlock* getExit() { return p_bb; }
- virtual ir::BasicBlock* getFirstBB() { return p_bb; }
- private:
- ir::BasicBlock *p_bb;
- };
-
- /* a sequence of nodes */
- class BlockNode : public Node
- {
- public:
- BlockNode(NodeList& children) : Node(Block, children) {}
- virtual ~BlockNode(){}
- };
-
- /* If-Then structure node */
- class IfThenNode : public Node
- {
- public:
- IfThenNode(Node* cond, Node* ifTrue) : Node(IfThen, BuildChildren(cond, ifTrue)) {}
- virtual ~IfThenNode() {}
-
- private:
- const NodeList BuildChildren(Node* cond, Node* ifTrue)
- {
- NodeList children;
- children.push_back(cond);
- children.push_back(ifTrue);
- return children;
- }
- };
-
- /* If-Else structure node */
- class IfElseNode : public Node
- {
- public:
- IfElseNode(Node* cond, Node* ifTrue, Node* ifFalse) : Node(IfElse, BuildChildren(cond, ifTrue, ifFalse)) {}
- virtual ~IfElseNode() {}
-
- private:
- const NodeList BuildChildren(Node* cond, Node* ifTrue, Node* ifFalse)
- {
- NodeList children;
- children.push_back(cond);
- children.push_back(ifTrue);
- children.push_back(ifFalse);
- return children;
- }
- };
-
- /* Self loop structure node */
- class SelfLoopNode : public Node
- {
- public:
- SelfLoopNode(Node* node) : Node(SelfLoop, BuildChildren(node)) {}
- virtual ~SelfLoopNode() {}
- virtual ir::BasicBlock* getEntry()
- {
- return (*(children.begin()))->getEntry();
- }
- virtual ir::BasicBlock* getExit()
- {
- return (*(children.begin()))->getExit();
- }
-
- private:
- const NodeList BuildChildren(Node *node)
- {
- NodeList children;
- children.push_back(node);
- return children;
- }
- };
-
- /* While loop structure node */
- class WhileLoopNode : public Node
- {
- public:
- WhileLoopNode(Node* cond, Node* execute) : Node(WhileLoop, BuildChildren(cond, execute)) {}
- virtual ~WhileLoopNode() {}
- virtual ir::BasicBlock* getEntry()
- {
- return (*(children.begin()))->getEntry();
- }
- virtual ir::BasicBlock* getExit()
- {
- return (*(children.begin()))->getExit();
- }
-
- private:
- const NodeList BuildChildren(Node* cond, Node* execute)
- {
- NodeList children;
- children.push_back(cond);
- children.push_back(execute);
- return children;
- }
-
- };
-
- /* Natural loop structure node */
- class NaturalLoopNode : public Node
- {
- public:
- NaturalLoopNode(const NodeList& children): Node(NaturalLoop, children){}
- virtual ~NaturalLoopNode() {}
- virtual ir::BasicBlock* getEntry()
- {
- //TODO implement it
- return NULL;
- }
- virtual ir::BasicBlock* getExit()
- {
- //TODO implement it
- return NULL;
- }
- };
-
- /* computes the control tree, and do the structure identification during the computation */
- class ControlTree
- {
- public:
- void analyze();
-
- ControlTree(ir::Function* fn) { this->fn = fn; }
- ~ControlTree();
-
- private:
- /* create a sequence of BasicBlockNodes, which are refered to the basic blocks in the function */
- void initializeNodes();
- /* insert a new Node, and returns the pointer of the node */
- Node* insertNode(Node *);
- /* do the structural analysis */
- void structuralAnalysis(Node * entry);
- /* do the dfs post order traverse of the current CFG */
- void DFSPostOrder(Node *start);
- /* returns true if there is a (possibly empty) path from m to k that does not pass through n */
- bool path(Node *m, Node *k, Node *n = NULL);
- /* link region node into abstract flowgraph, adjust the predecessor and successor functions, and augment the control tree */
- void reduce(Node* node, NodeSet nodeSet);
- /* adds node to the control tree, inserts node into _post
- * at the highest-numbered position of a node in nodeSet, removes
- * the nodes in nodeSet from _post, compacts the remaining nodes at
- * the beginning of _post, and sets _postCtr to the index of node
- * in the resulting postorder */
- void compact(Node* node, NodeSet nodeSet);
- Node* getNodesEntry() const { return nodes_entry;}
- /* determines whether node is the entry node of an acyclic
- * control structure and returns its region. Stores in nset the set
- * of nodes in the identified control structure */
- Node* acyclicRegionType(Node* node, NodeSet& nset);
- /* determines whether node is the entry node of a cyclic
- * control structure and returns its region. Stores in nset the set
- * of nodes in the identified control structure */
- Node* cyclicRegionType(Node*, NodeList&);
- /* is this a cyclic region? */
- bool isCyclic(Node*);
- /* is this a back edge? */
- bool isBackedge(const Node*, const 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 */
- void markNeedEndif(Node * n, bool status);
- /* mark all the ir::BasicBlocks' needIf of n as status */
- void markNeedIf(Node *, bool);
- /* insert IF instruction at the proper position of Node */
- void handleIfNode(Node *, ir::LabelIndex&, ir::LabelIndex&);
- /* insert ENDIF instruction at the proper position of Node, this Node is
- the 'then' node of identified if-then structure */
- void handleThenNode(Node *, ir::LabelIndex&);
- /* handle the then node of identified if-else structure */
- void handleThenNode2(Node *, Node *, ir::LabelIndex);
- /* insert ELSE instruction at the proper position of Node */
- void handleElseNode(Node *, ir::LabelIndex&, ir::LabelIndex&);
- /* this calls other functions to finish the handling of identified structure blocks */
- void handleStructuredNodes();
- std::set<int> getStructureBasicBlocksIndex(Node *, std::vector<ir::BasicBlock *> &);
- std::set<ir::BasicBlock *> getStructureBasicBlocks(Node*);
- /* get livein of bb */
- void getLiveIn(ir::BasicBlock& bb, std::set<ir::Register>& livein);
- /* see comment of BasicBlock::liveout in function.hpp for detail. */
- void calculateNecessaryLiveout();
- /* get the exectutive sequence of structure n */
- void getStructureSequence(Node* n, std::vector<ir::BasicBlock*> &v);
- private:
- ir::Function *fn;
- NodeVector nodes;
- Node* nodes_entry;
- unordered_map<ir::BasicBlock *, Node *> bbmap;
- NodeList post_order;
- NodeSet visited;
- NodeList::iterator post_ctr;
- };
-}
-#endif
diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
index 4ea722af..f16bf0f9 100644
--- a/backend/src/llvm/llvm_to_gen.cpp
+++ b/backend/src/llvm/llvm_to_gen.cpp
@@ -61,7 +61,6 @@
#include "sys/cvar.hpp"
#include "sys/platform.hpp"
#include "ir/unit.hpp"
-#include "ir/structural_analysis.hpp"
#include <clang/CodeGen/CodeGenAction.h>
@@ -309,18 +308,6 @@ namespace gbe
// Print the code extra optimization passes
OUTPUT_BITCODE(AFTER_GEN, mod);
- const ir::Unit::FunctionSet& fs = unit.getFunctionSet();
- ir::Unit::FunctionSet::const_iterator iter = fs.begin();
- while(iter != fs.end())
- {
- analysis::ControlTree *ct = new analysis::ControlTree(iter->second);
- ct->analyze();
- delete ct;
- if (OCL_OUTPUT_CFG_GEN_IR)
- iter->second->outputCFG();
- iter++;
- }
-
delete libraryInfo;
return true;
}