[DebugInfo] Re-implement LexicalScopes dominance method, add unit tests
Way back in D24994, the combination of LexicalScopes::dominates and
LiveDebugValues was identified as having worst-case quadratic complexity,
but it wasn't triggered by any code path at the time. I've since run into a
scenario where this occurs, in a very large basic block where large numbers
of inlined DBG_VALUEs are present.
The quadratic-ness comes from LiveDebugValues::join calling "dominates" on
every variable location, and LexicalScopes::dominates potentially touching
every instruction in a block to test for the presence of a scope. We have,
however, already computed the presence of scopes in blocks, in the
"InstrRanges" of each scope. This patch switches the dominates method to
examine whether a block is present in a scope's InsnRanges, avoiding
walking through the whole block.
At the same time, fix getMachineBasicBlocks to account for the fact that
InsnRanges can cover multiple blocks, and add some unit tests, as Lexical
Scopes didn't have any.
Differential revision: https://reviews.llvm.org/D73725
2020-02-28 11:41:23 +01:00
|
|
|
// Add a few Bogus backend classes so we can create MachineInstrs without
|
|
|
|
// depending on a real target.
|
|
|
|
class BogusTargetLowering : public TargetLowering {
|
|
|
|
public:
|
|
|
|
BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BogusFrameLowering : public TargetFrameLowering {
|
|
|
|
public:
|
|
|
|
BogusFrameLowering()
|
|
|
|
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 4) {}
|
|
|
|
|
|
|
|
void emitPrologue(MachineFunction &MF,
|
|
|
|
MachineBasicBlock &MBB) const override {}
|
|
|
|
void emitEpilogue(MachineFunction &MF,
|
|
|
|
MachineBasicBlock &MBB) const override {}
|
|
|
|
bool hasFP(const MachineFunction &MF) const override { return false; }
|
|
|
|
};
|
|
|
|
|
|
|
|
static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};
|
|
|
|
|
|
|
|
class BogusRegisterInfo : public TargetRegisterInfo {
|
|
|
|
public:
|
|
|
|
BogusRegisterInfo()
|
|
|
|
: TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses,
|
|
|
|
nullptr, nullptr, LaneBitmask(~0u), nullptr) {
|
|
|
|
InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
|
|
|
|
nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
const MCPhysReg *
|
|
|
|
getCalleeSavedRegs(const MachineFunction *MF) const override {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
ArrayRef<const uint32_t *> getRegMasks() const override { return None; }
|
|
|
|
ArrayRef<const char *> getRegMaskNames() const override { return None; }
|
|
|
|
BitVector getReservedRegs(const MachineFunction &MF) const override {
|
|
|
|
return BitVector();
|
|
|
|
}
|
|
|
|
const RegClassWeight &
|
|
|
|
getRegClassWeight(const TargetRegisterClass *RC) const override {
|
|
|
|
static RegClassWeight Bogus{1, 16};
|
|
|
|
return Bogus;
|
|
|
|
}
|
|
|
|
unsigned getRegUnitWeight(unsigned RegUnit) const override { return 1; }
|
|
|
|
unsigned getNumRegPressureSets() const override { return 0; }
|
|
|
|
const char *getRegPressureSetName(unsigned Idx) const override {
|
|
|
|
return "bogus";
|
|
|
|
}
|
|
|
|
unsigned getRegPressureSetLimit(const MachineFunction &MF,
|
|
|
|
unsigned Idx) const override {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
const int *
|
|
|
|
getRegClassPressureSets(const TargetRegisterClass *RC) const override {
|
|
|
|
static const int Bogus[] = {0, -1};
|
|
|
|
return &Bogus[0];
|
|
|
|
}
|
|
|
|
const int *getRegUnitPressureSets(unsigned RegUnit) const override {
|
|
|
|
static const int Bogus[] = {0, -1};
|
|
|
|
return &Bogus[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
Register getFrameRegister(const MachineFunction &MF) const override {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
|
|
|
|
unsigned FIOperandNum,
|
|
|
|
RegScavenger *RS = nullptr) const override {}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BogusSubtarget : public TargetSubtargetInfo {
|
|
|
|
public:
|
|
|
|
BogusSubtarget(TargetMachine &TM)
|
2020-08-14 23:56:54 +02:00
|
|
|
: TargetSubtargetInfo(Triple(""), "", "", "", {}, {}, nullptr, nullptr,
|
[DebugInfo] Re-implement LexicalScopes dominance method, add unit tests
Way back in D24994, the combination of LexicalScopes::dominates and
LiveDebugValues was identified as having worst-case quadratic complexity,
but it wasn't triggered by any code path at the time. I've since run into a
scenario where this occurs, in a very large basic block where large numbers
of inlined DBG_VALUEs are present.
The quadratic-ness comes from LiveDebugValues::join calling "dominates" on
every variable location, and LexicalScopes::dominates potentially touching
every instruction in a block to test for the presence of a scope. We have,
however, already computed the presence of scopes in blocks, in the
"InstrRanges" of each scope. This patch switches the dominates method to
examine whether a block is present in a scope's InsnRanges, avoiding
walking through the whole block.
At the same time, fix getMachineBasicBlocks to account for the fact that
InsnRanges can cover multiple blocks, and add some unit tests, as Lexical
Scopes didn't have any.
Differential revision: https://reviews.llvm.org/D73725
2020-02-28 11:41:23 +01:00
|
|
|
nullptr, nullptr, nullptr, nullptr),
|
|
|
|
FL(), TL(TM) {}
|
|
|
|
~BogusSubtarget() override {}
|
|
|
|
|
|
|
|
const TargetFrameLowering *getFrameLowering() const override { return &FL; }
|
|
|
|
|
|
|
|
const TargetLowering *getTargetLowering() const override { return &TL; }
|
|
|
|
|
|
|
|
const TargetInstrInfo *getInstrInfo() const override { return &TII; }
|
|
|
|
|
|
|
|
const TargetRegisterInfo *getRegisterInfo() const override { return &TRI; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
BogusFrameLowering FL;
|
|
|
|
BogusRegisterInfo TRI;
|
|
|
|
BogusTargetLowering TL;
|
|
|
|
TargetInstrInfo TII;
|
|
|
|
};
|
|
|
|
|
2020-04-07 22:09:29 +02:00
|
|
|
static TargetOptions getTargetOptionsForBogusMachine() {
|
|
|
|
TargetOptions Opts;
|
|
|
|
Opts.EmitCallSiteInfo = true;
|
|
|
|
return Opts;
|
|
|
|
}
|
|
|
|
|
[DebugInfo] Re-implement LexicalScopes dominance method, add unit tests
Way back in D24994, the combination of LexicalScopes::dominates and
LiveDebugValues was identified as having worst-case quadratic complexity,
but it wasn't triggered by any code path at the time. I've since run into a
scenario where this occurs, in a very large basic block where large numbers
of inlined DBG_VALUEs are present.
The quadratic-ness comes from LiveDebugValues::join calling "dominates" on
every variable location, and LexicalScopes::dominates potentially touching
every instruction in a block to test for the presence of a scope. We have,
however, already computed the presence of scopes in blocks, in the
"InstrRanges" of each scope. This patch switches the dominates method to
examine whether a block is present in a scope's InsnRanges, avoiding
walking through the whole block.
At the same time, fix getMachineBasicBlocks to account for the fact that
InsnRanges can cover multiple blocks, and add some unit tests, as Lexical
Scopes didn't have any.
Differential revision: https://reviews.llvm.org/D73725
2020-02-28 11:41:23 +01:00
|
|
|
class BogusTargetMachine : public LLVMTargetMachine {
|
|
|
|
public:
|
|
|
|
BogusTargetMachine()
|
2020-04-07 22:09:29 +02:00
|
|
|
: LLVMTargetMachine(Target(), "", Triple(""), "", "",
|
|
|
|
getTargetOptionsForBogusMachine(), Reloc::Static,
|
|
|
|
CodeModel::Small, CodeGenOpt::Default),
|
[DebugInfo] Re-implement LexicalScopes dominance method, add unit tests
Way back in D24994, the combination of LexicalScopes::dominates and
LiveDebugValues was identified as having worst-case quadratic complexity,
but it wasn't triggered by any code path at the time. I've since run into a
scenario where this occurs, in a very large basic block where large numbers
of inlined DBG_VALUEs are present.
The quadratic-ness comes from LiveDebugValues::join calling "dominates" on
every variable location, and LexicalScopes::dominates potentially touching
every instruction in a block to test for the presence of a scope. We have,
however, already computed the presence of scopes in blocks, in the
"InstrRanges" of each scope. This patch switches the dominates method to
examine whether a block is present in a scope's InsnRanges, avoiding
walking through the whole block.
At the same time, fix getMachineBasicBlocks to account for the fact that
InsnRanges can cover multiple blocks, and add some unit tests, as Lexical
Scopes didn't have any.
Differential revision: https://reviews.llvm.org/D73725
2020-02-28 11:41:23 +01:00
|
|
|
ST(*this) {}
|
|
|
|
|
|
|
|
~BogusTargetMachine() override {}
|
|
|
|
|
|
|
|
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
|
|
|
|
return &ST;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
BogusSubtarget ST;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::unique_ptr<BogusTargetMachine> createTargetMachine() {
|
|
|
|
return std::make_unique<BogusTargetMachine>();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<MachineFunction> createMachineFunction(LLVMContext &Ctx,
|
|
|
|
Module &M) {
|
|
|
|
auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
|
|
|
|
auto F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &M);
|
|
|
|
|
|
|
|
auto TM = createTargetMachine();
|
|
|
|
unsigned FunctionNum = 42;
|
|
|
|
MachineModuleInfo MMI(TM.get());
|
|
|
|
const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(*F);
|
|
|
|
|
|
|
|
return std::make_unique<MachineFunction>(*F, *TM, STI, FunctionNum, MMI);
|
|
|
|
}
|
|
|
|
|