llvm-project/llvm/lib/Target/AMDGPU/SIInsertNopsPass.cpp

95 lines
3.0 KiB
C++

//===--- SIInsertNopsPass.cpp - Use predicates for control flow -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// \brief Insert two S_NOP instructions for every high level source statement.
///
/// Tools, such as debugger, need to pause execution based on user input (i.e.
/// breakpoint). In order to do this, two S_NOP instructions are inserted for
/// each high level source statement: one before first isa instruction of high
/// level source statement, and one after last isa instruction of high level
/// source statement. Further, debugger may replace S_NOP instructions with
/// S_TRAP instructions based on user input.
//
//===----------------------------------------------------------------------===//
#include "SIInstrInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
using namespace llvm;
#define DEBUG_TYPE "si-insert-nops"
#define PASS_NAME "SI Insert Nops"
namespace {
class SIInsertNops : public MachineFunctionPass {
public:
static char ID;
SIInsertNops() : MachineFunctionPass(ID) { }
const char *getPassName() const override { return PASS_NAME; }
bool runOnMachineFunction(MachineFunction &MF) override;
};
} // anonymous namespace
INITIALIZE_PASS(SIInsertNops, DEBUG_TYPE, PASS_NAME, false, false)
char SIInsertNops::ID = 0;
char &llvm::SIInsertNopsID = SIInsertNops::ID;
FunctionPass *llvm::createSIInsertNopsPass() {
return new SIInsertNops();
}
bool SIInsertNops::runOnMachineFunction(MachineFunction &MF) {
const SIInstrInfo *TII =
static_cast<const SIInstrInfo*>(MF.getSubtarget().getInstrInfo());
DenseMap<unsigned, MachineBasicBlock::iterator> LineToInst;
for (auto MBB = MF.begin(); MBB != MF.end(); ++MBB) {
for (auto MI = MBB->begin(); MI != MBB->end(); ++MI) {
if (MI->isDebugValue() || !MI->getDebugLoc()) {
continue;
}
auto DL = MI->getDebugLoc();
auto CL = DL.getLine();
auto LineToInstEntry = LineToInst.find(CL);
if (LineToInstEntry == LineToInst.end()) {
BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::S_NOP))
.addImm(0);
LineToInst.insert(std::make_pair(CL, MI));
} else {
LineToInstEntry->second = MI;
}
}
}
for (auto LineToInstEntry = LineToInst.begin();
LineToInstEntry != LineToInst.end(); ++LineToInstEntry) {
auto MBB = LineToInstEntry->second->getParent();
auto DL = LineToInstEntry->second->getDebugLoc();
MachineBasicBlock::iterator MI = LineToInstEntry->second;
++MI;
if (MI != MBB->end()) {
BuildMI(*MBB, *MI, DL, TII->get(AMDGPU::S_NOP))
.addImm(0);
}
}
MachineBasicBlock &MBB = MF.front();
MachineInstr &MI = MBB.front();
BuildMI(MBB, MI, DebugLoc(), TII->get(AMDGPU::S_NOP))
.addImm(0);
return true;
}