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