blob: 83dfe120899a40e92e1a7318fa041d5dc889a357 [file] [log] [blame]
Justin Holewinski49683f32012-05-04 20:18:50 +00001//===- 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
Chandler Carruthd04a8d42012-12-03 16:50:05 +000014#include "NVPTXSplitBBatBar.h"
15#include "NVPTXUtilities.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000016#include "llvm/IR/Function.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/IntrinsicInst.h"
19#include "llvm/IR/Intrinsics.h"
Justin Holewinski49683f32012-05-04 20:18:50 +000020#include "llvm/Support/InstIterator.h"
Justin Holewinski49683f32012-05-04 20:18:50 +000021
22using namespace llvm;
23
Justin Holewinski3639ce22013-03-30 14:29:21 +000024namespace llvm { FunctionPass *createSplitBBatBarPass(); }
Justin Holewinski49683f32012-05-04 20:18:50 +000025
26char NVPTXSplitBBatBar::ID = 0;
27
28bool NVPTXSplitBBatBar::runOnFunction(Function &F) {
29
30 SmallVector<Instruction *, 4> SplitPoints;
31 bool changed = false;
32
33 // Collect all the split points in SplitPoints
34 for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
35 BasicBlock::iterator IB = BI->begin();
36 BasicBlock::iterator II = IB;
37 BasicBlock::iterator IE = BI->end();
38
39 // Skit the first intruction. No splitting is needed at this
40 // point even if this is a bar.
41 while (II != IE) {
42 if (IntrinsicInst *inst = dyn_cast<IntrinsicInst>(II)) {
43 Intrinsic::ID id = inst->getIntrinsicID();
44 // If this is a barrier, split at this instruction
45 // and the next instruction.
46 if (llvm::isBarrierIntrinsic(id)) {
47 if (II != IB)
48 SplitPoints.push_back(II);
49 II++;
50 if ((II != IE) && (!II->isTerminator())) {
51 SplitPoints.push_back(II);
52 II++;
53 }
54 continue;
55 }
56 }
57 II++;
58 }
59 }
60
61 for (unsigned i = 0; i != SplitPoints.size(); i++) {
62 changed = true;
63 Instruction *inst = SplitPoints[i];
64 inst->getParent()->splitBasicBlock(inst, "bar_split");
65 }
66
67 return changed;
68}
69
70// This interface will most likely not be necessary, because this pass will
71// not be invoked by the driver, but will be used as a prerequisite to
72// another pass.
Justin Holewinski3639ce22013-03-30 14:29:21 +000073FunctionPass *llvm::createSplitBBatBarPass() { return new NVPTXSplitBBatBar(); }