summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp105
1 files changed, 72 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 4db5d1c2ea1..95f6274aa06 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -19,6 +19,7 @@
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/LowLevelType.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -75,11 +76,16 @@
using namespace llvm;
+static cl::opt<bool>
+ EnableCSEInIRTranslator("enable-cse-in-irtranslator",
+ cl::desc("Should enable CSE in irtranslator"),
+ cl::Optional, cl::init(false));
char IRTranslator::ID = 0;
INITIALIZE_PASS_BEGIN(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_END(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
@@ -108,18 +114,21 @@ IRTranslator::IRTranslator() : MachineFunctionPass(ID) {
namespace {
/// Verify that every instruction created has the same DILocation as the
/// instruction being translated.
-class DILocationVerifier : MachineFunction::Delegate {
- MachineFunction &MF;
+class DILocationVerifier : public GISelChangeObserver {
const Instruction *CurrInst = nullptr;
public:
- DILocationVerifier(MachineFunction &MF) : MF(MF) { MF.setDelegate(this); }
- ~DILocationVerifier() { MF.resetDelegate(this); }
+ DILocationVerifier() = default;
+ ~DILocationVerifier() = default;
const Instruction *getCurrentInst() const { return CurrInst; }
void setCurrentInst(const Instruction *Inst) { CurrInst = Inst; }
- void MF_HandleInsertion(const MachineInstr &MI) override {
+ void erasingInstr(MachineInstr &MI) override {}
+ void changingInstr(MachineInstr &MI) override {}
+ void changedInstr(MachineInstr &MI) override {}
+
+ void createdInstr(MachineInstr &MI) override {
assert(getCurrentInst() && "Inserted instruction without a current MI");
// Only print the check message if we're actually checking it.
@@ -130,7 +139,6 @@ public:
assert(CurrInst->getDebugLoc() == MI.getDebugLoc() &&
"Line info was not transferred to all instructions");
}
- void MF_HandleRemoval(const MachineInstr &MI) override {}
};
} // namespace
#endif // ifndef NDEBUG
@@ -139,6 +147,7 @@ public:
void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<StackProtector>();
AU.addRequired<TargetPassConfig>();
+ AU.addRequired<GISelCSEAnalysisWrapperPass>();
getSelectionDAGFallbackAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -1553,12 +1562,14 @@ bool IRTranslator::translateAtomicRMW(const User &U,
void IRTranslator::finishPendingPhis() {
#ifndef NDEBUG
- DILocationVerifier Verifier(*MF);
+ DILocationVerifier Verifier;
+ GISelObserverWrapper WrapperObserver(&Verifier);
+ RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver);
#endif // ifndef NDEBUG
for (auto &Phi : PendingPHIs) {
const PHINode *PI = Phi.first;
ArrayRef<MachineInstr *> ComponentPHIs = Phi.second;
- EntryBuilder.setDebugLoc(PI->getDebugLoc());
+ EntryBuilder->setDebugLoc(PI->getDebugLoc());
#ifndef NDEBUG
Verifier.setCurrentInst(PI);
#endif // ifndef NDEBUG
@@ -1599,11 +1610,12 @@ bool IRTranslator::valueIsSplit(const Value &V,
}
bool IRTranslator::translate(const Instruction &Inst) {
- CurBuilder.setDebugLoc(Inst.getDebugLoc());
- EntryBuilder.setDebugLoc(Inst.getDebugLoc());
+ CurBuilder->setDebugLoc(Inst.getDebugLoc());
+ EntryBuilder->setDebugLoc(Inst.getDebugLoc());
switch(Inst.getOpcode()) {
-#define HANDLE_INST(NUM, OPCODE, CLASS) \
- case Instruction::OPCODE: return translate##OPCODE(Inst, CurBuilder);
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ case Instruction::OPCODE: \
+ return translate##OPCODE(Inst, *CurBuilder.get());
#include "llvm/IR/Instruction.def"
default:
return false;
@@ -1612,11 +1624,11 @@ bool IRTranslator::translate(const Instruction &Inst) {
bool IRTranslator::translate(const Constant &C, unsigned Reg) {
if (auto CI = dyn_cast<ConstantInt>(&C))
- EntryBuilder.buildConstant(Reg, *CI);
+ EntryBuilder->buildConstant(Reg, *CI);
else if (auto CF = dyn_cast<ConstantFP>(&C))
- EntryBuilder.buildFConstant(Reg, *CF);
+ EntryBuilder->buildFConstant(Reg, *CF);
else if (isa<UndefValue>(C))
- EntryBuilder.buildUndef(Reg);
+ EntryBuilder->buildUndef(Reg);
else if (isa<ConstantPointerNull>(C)) {
// As we are trying to build a constant val of 0 into a pointer,
// insert a cast to make them correct with respect to types.
@@ -1624,9 +1636,9 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
auto *ZeroTy = Type::getIntNTy(C.getContext(), NullSize);
auto *ZeroVal = ConstantInt::get(ZeroTy, 0);
unsigned ZeroReg = getOrCreateVReg(*ZeroVal);
- EntryBuilder.buildCast(Reg, ZeroReg);
+ EntryBuilder->buildCast(Reg, ZeroReg);
} else if (auto GV = dyn_cast<GlobalValue>(&C))
- EntryBuilder.buildGlobalValue(Reg, GV);
+ EntryBuilder->buildGlobalValue(Reg, GV);
else if (auto CAZ = dyn_cast<ConstantAggregateZero>(&C)) {
if (!CAZ->getType()->isVectorTy())
return false;
@@ -1638,7 +1650,7 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
Constant &Elt = *CAZ->getElementValue(i);
Ops.push_back(getOrCreateVReg(Elt));
}
- EntryBuilder.buildBuildVector(Reg, Ops);
+ EntryBuilder->buildBuildVector(Reg, Ops);
} else if (auto CV = dyn_cast<ConstantDataVector>(&C)) {
// Return the scalar if it is a <1 x Ty> vector.
if (CV->getNumElements() == 1)
@@ -1648,11 +1660,12 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
Constant &Elt = *CV->getElementAsConstant(i);
Ops.push_back(getOrCreateVReg(Elt));
}
- EntryBuilder.buildBuildVector(Reg, Ops);
+ EntryBuilder->buildBuildVector(Reg, Ops);
} else if (auto CE = dyn_cast<ConstantExpr>(&C)) {
switch(CE->getOpcode()) {
-#define HANDLE_INST(NUM, OPCODE, CLASS) \
- case Instruction::OPCODE: return translate##OPCODE(*CE, EntryBuilder);
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ case Instruction::OPCODE: \
+ return translate##OPCODE(*CE, *EntryBuilder.get());
#include "llvm/IR/Instruction.def"
default:
return false;
@@ -1664,9 +1677,9 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
for (unsigned i = 0; i < CV->getNumOperands(); ++i) {
Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
}
- EntryBuilder.buildBuildVector(Reg, Ops);
+ EntryBuilder->buildBuildVector(Reg, Ops);
} else if (auto *BA = dyn_cast<BlockAddress>(&C)) {
- EntryBuilder.buildBlockAddress(Reg, BA);
+ EntryBuilder->buildBlockAddress(Reg, BA);
} else
return false;
@@ -1683,8 +1696,8 @@ void IRTranslator::finalizeFunction() {
// MachineIRBuilder::DebugLoc can outlive the DILocation it holds. Clear it
// to avoid accessing free’d memory (in runOnMachineFunction) and to avoid
// destroying it twice (in ~IRTranslator() and ~LLVMContext())
- EntryBuilder = MachineIRBuilder();
- CurBuilder = MachineIRBuilder();
+ EntryBuilder.reset();
+ CurBuilder.reset();
}
bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
@@ -1692,12 +1705,30 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
const Function &F = MF->getFunction();
if (F.empty())
return false;
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
+ // Set the CSEConfig and run the analysis.
+ GISelCSEInfo *CSEInfo = nullptr;
+ TPC = &getAnalysis<TargetPassConfig>();
+ bool IsO0 = TPC->getOptLevel() == CodeGenOpt::Level::None;
+ // Disable CSE for O0.
+ bool EnableCSE = !IsO0 && EnableCSEInIRTranslator;
+ if (EnableCSE) {
+ EntryBuilder = make_unique<CSEMIRBuilder>(CurMF);
+ std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
+ CSEInfo = &Wrapper.get(std::move(Config));
+ EntryBuilder->setCSEInfo(CSEInfo);
+ CurBuilder = make_unique<CSEMIRBuilder>(CurMF);
+ CurBuilder->setCSEInfo(CSEInfo);
+ } else {
+ EntryBuilder = make_unique<MachineIRBuilder>();
+ CurBuilder = make_unique<MachineIRBuilder>();
+ }
CLI = MF->getSubtarget().getCallLowering();
- CurBuilder.setMF(*MF);
- EntryBuilder.setMF(*MF);
+ CurBuilder->setMF(*MF);
+ EntryBuilder->setMF(*MF);
MRI = &MF->getRegInfo();
DL = &F.getParent()->getDataLayout();
- TPC = &getAnalysis<TargetPassConfig>();
ORE = llvm::make_unique<OptimizationRemarkEmitter>(&F);
assert(PendingPHIs.empty() && "stale PHIs");
@@ -1716,7 +1747,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
// Setup a separate basic-block for the arguments and constants
MachineBasicBlock *EntryBB = MF->CreateMachineBasicBlock();
MF->push_back(EntryBB);
- EntryBuilder.setMBB(*EntryBB);
+ EntryBuilder->setMBB(*EntryBB);
// Create all blocks, in IR order, to preserve the layout.
for (const BasicBlock &BB: F) {
@@ -1753,7 +1784,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
}
}
- if (!CLI->lowerFormalArguments(EntryBuilder, F, VRegArgs)) {
+ if (!CLI->lowerFormalArguments(*EntryBuilder.get(), F, VRegArgs)) {
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
F.getSubprogram(), &F.getEntryBlock());
R << "unable to lower arguments: " << ore::NV("Prototype", F.getType());
@@ -1770,22 +1801,27 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
assert(VRegs.empty() && "VRegs already populated?");
VRegs.push_back(VArg);
} else {
- unpackRegs(*ArgIt, VArg, EntryBuilder);
+ unpackRegs(*ArgIt, VArg, *EntryBuilder.get());
}
ArgIt++;
}
// Need to visit defs before uses when translating instructions.
+ GISelObserverWrapper WrapperObserver;
+ if (EnableCSE && CSEInfo)
+ WrapperObserver.addObserver(CSEInfo);
{
ReversePostOrderTraversal<const Function *> RPOT(&F);
#ifndef NDEBUG
- DILocationVerifier Verifier(*MF);
+ DILocationVerifier Verifier;
+ WrapperObserver.addObserver(&Verifier);
#endif // ifndef NDEBUG
+ RAIIDelegateInstaller DelInstall(*MF, &WrapperObserver);
for (const BasicBlock *BB : RPOT) {
MachineBasicBlock &MBB = getMBB(*BB);
// Set the insertion point of all the following translations to
// the end of this basic block.
- CurBuilder.setMBB(MBB);
+ CurBuilder->setMBB(MBB);
for (const Instruction &Inst : *BB) {
#ifndef NDEBUG
@@ -1810,6 +1846,9 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
return false;
}
}
+#ifndef NDEBUG
+ WrapperObserver.removeObserver(&Verifier);
+#endif
}
finishPendingPhis();