1239310Sdim//===- NVPTXSplitBBatBar.cpp - Split BB at Barrier  --*- C++ -*--===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim// Split basic blocks so that a basic block that contains a barrier instruction
10239310Sdim// only contains the barrier instruction.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14252723Sdim#include "NVPTXSplitBBatBar.h"
15252723Sdim#include "NVPTXUtilities.h"
16252723Sdim#include "llvm/IR/Function.h"
17252723Sdim#include "llvm/IR/Instructions.h"
18252723Sdim#include "llvm/IR/IntrinsicInst.h"
19252723Sdim#include "llvm/IR/Intrinsics.h"
20239310Sdim#include "llvm/Support/InstIterator.h"
21239310Sdim
22239310Sdimusing namespace llvm;
23239310Sdim
24252723Sdimnamespace llvm { FunctionPass *createSplitBBatBarPass(); }
25239310Sdim
26239310Sdimchar NVPTXSplitBBatBar::ID = 0;
27239310Sdim
28239310Sdimbool NVPTXSplitBBatBar::runOnFunction(Function &F) {
29239310Sdim
30239310Sdim  SmallVector<Instruction *, 4> SplitPoints;
31239310Sdim  bool changed = false;
32239310Sdim
33239310Sdim  // Collect all the split points in SplitPoints
34239310Sdim  for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
35239310Sdim    BasicBlock::iterator IB = BI->begin();
36239310Sdim    BasicBlock::iterator II = IB;
37239310Sdim    BasicBlock::iterator IE = BI->end();
38239310Sdim
39263509Sdim    // Skit the first instruction. No splitting is needed at this
40239310Sdim    // point even if this is a bar.
41239310Sdim    while (II != IE) {
42239310Sdim      if (IntrinsicInst *inst = dyn_cast<IntrinsicInst>(II)) {
43239310Sdim        Intrinsic::ID id = inst->getIntrinsicID();
44239310Sdim        // If this is a barrier, split at this instruction
45239310Sdim        // and the next instruction.
46239310Sdim        if (llvm::isBarrierIntrinsic(id)) {
47239310Sdim          if (II != IB)
48239310Sdim            SplitPoints.push_back(II);
49239310Sdim          II++;
50239310Sdim          if ((II != IE) && (!II->isTerminator())) {
51239310Sdim            SplitPoints.push_back(II);
52239310Sdim            II++;
53239310Sdim          }
54239310Sdim          continue;
55239310Sdim        }
56239310Sdim      }
57239310Sdim      II++;
58239310Sdim    }
59239310Sdim  }
60239310Sdim
61239310Sdim  for (unsigned i = 0; i != SplitPoints.size(); i++) {
62239310Sdim    changed = true;
63239310Sdim    Instruction *inst = SplitPoints[i];
64239310Sdim    inst->getParent()->splitBasicBlock(inst, "bar_split");
65239310Sdim  }
66239310Sdim
67239310Sdim  return changed;
68239310Sdim}
69239310Sdim
70239310Sdim// This interface will most likely not be necessary, because this pass will
71239310Sdim// not be invoked by the driver, but will be used as a prerequisite to
72239310Sdim// another pass.
73252723SdimFunctionPass *llvm::createSplitBBatBarPass() { return new NVPTXSplitBBatBar(); }
74