]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Target/NVPTX/NVPTXSplitBBatBar.cpp
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / lib / Target / NVPTX / NVPTXSplitBBatBar.cpp
1 //===- NVPTXSplitBBatBar.cpp - Split BB at Barrier  --*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Split basic blocks so that a basic block that contains a barrier instruction
10 // only contains the barrier instruction.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Function.h"
15 #include "llvm/Instructions.h"
16 #include "llvm/Intrinsics.h"
17 #include "llvm/IntrinsicInst.h"
18 #include "llvm/Support/InstIterator.h"
19 #include "NVPTXUtilities.h"
20 #include "NVPTXSplitBBatBar.h"
21
22 using namespace llvm;
23
24 namespace llvm {
25 FunctionPass *createSplitBBatBarPass();
26 }
27
28 char NVPTXSplitBBatBar::ID = 0;
29
30 bool NVPTXSplitBBatBar::runOnFunction(Function &F) {
31
32   SmallVector<Instruction *, 4> SplitPoints;
33   bool changed = false;
34
35   // Collect all the split points in SplitPoints
36   for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
37     BasicBlock::iterator IB = BI->begin();
38     BasicBlock::iterator II = IB;
39     BasicBlock::iterator IE = BI->end();
40
41     // Skit the first intruction. No splitting is needed at this
42     // point even if this is a bar.
43     while (II != IE) {
44       if (IntrinsicInst *inst = dyn_cast<IntrinsicInst>(II)) {
45         Intrinsic::ID id = inst->getIntrinsicID();
46         // If this is a barrier, split at this instruction
47         // and the next instruction.
48         if (llvm::isBarrierIntrinsic(id)) {
49           if (II != IB)
50             SplitPoints.push_back(II);
51           II++;
52           if ((II != IE) && (!II->isTerminator())) {
53             SplitPoints.push_back(II);
54             II++;
55           }
56           continue;
57         }
58       }
59       II++;
60     }
61   }
62
63   for (unsigned i = 0; i != SplitPoints.size(); i++) {
64     changed = true;
65     Instruction *inst = SplitPoints[i];
66     inst->getParent()->splitBasicBlock(inst, "bar_split");
67   }
68
69   return changed;
70 }
71
72 // This interface will most likely not be necessary, because this pass will
73 // not be invoked by the driver, but will be used as a prerequisite to
74 // another pass.
75 FunctionPass *llvm::createSplitBBatBarPass() {
76   return new NVPTXSplitBBatBar();
77 }