forked from OSchip/llvm-project
Recommit "Add a heap alloc site marker field to the ExtraInfo in MachineInstrs"
Summary: Fixes some things from original commit at https://reviews.llvm.org/D69136. The main change is that the heap alloc marker is always stored as ExtraInfo in the machine instruction instead of in the PointerSumType because it cannot hold more than 4 pointer types. Add instruction marker to MachineInstr ExtraInfo. This does almost the same thing as Pre/PostInstrSymbols, except that it doesn't create a label until printing instructions. This allows for labels to be put around instructions that are deleted/duplicated somewhere. Use this marker to track heap alloc site call instructions. Reviewers: rnk Subscribers: MatzeB, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69536
This commit is contained in:
parent
99046b873f
commit
742043047c
|
@ -326,10 +326,6 @@ class MachineFunction {
|
||||||
/// CodeView label annotations.
|
/// CodeView label annotations.
|
||||||
std::vector<std::pair<MCSymbol *, MDNode *>> CodeViewAnnotations;
|
std::vector<std::pair<MCSymbol *, MDNode *>> CodeViewAnnotations;
|
||||||
|
|
||||||
/// CodeView heapallocsites.
|
|
||||||
std::vector<std::tuple<MCSymbol *, MCSymbol *, const DIType *>>
|
|
||||||
CodeViewHeapAllocSites;
|
|
||||||
|
|
||||||
bool CallsEHReturn = false;
|
bool CallsEHReturn = false;
|
||||||
bool CallsUnwindInit = false;
|
bool CallsUnwindInit = false;
|
||||||
bool HasEHScopes = false;
|
bool HasEHScopes = false;
|
||||||
|
@ -804,10 +800,9 @@ public:
|
||||||
///
|
///
|
||||||
/// This is allocated on the function's allocator and so lives the life of
|
/// This is allocated on the function's allocator and so lives the life of
|
||||||
/// the function.
|
/// the function.
|
||||||
MachineInstr::ExtraInfo *
|
MachineInstr::ExtraInfo *createMIExtraInfo(
|
||||||
createMIExtraInfo(ArrayRef<MachineMemOperand *> MMOs,
|
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol = nullptr,
|
||||||
MCSymbol *PreInstrSymbol = nullptr,
|
MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr);
|
||||||
MCSymbol *PostInstrSymbol = nullptr);
|
|
||||||
|
|
||||||
/// Allocate a string and populate it with the given external symbol name.
|
/// Allocate a string and populate it with the given external symbol name.
|
||||||
const char *createExternalSymbolName(StringRef Name);
|
const char *createExternalSymbolName(StringRef Name);
|
||||||
|
@ -962,14 +957,6 @@ public:
|
||||||
return CodeViewAnnotations;
|
return CodeViewAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Record heapallocsites
|
|
||||||
void addCodeViewHeapAllocSite(MachineInstr *I, const MDNode *MD);
|
|
||||||
|
|
||||||
ArrayRef<std::tuple<MCSymbol *, MCSymbol *, const DIType *>>
|
|
||||||
getCodeViewHeapAllocSites() const {
|
|
||||||
return CodeViewHeapAllocSites;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a reference to the C++ typeinfo for the current function.
|
/// Return a reference to the C++ typeinfo for the current function.
|
||||||
const std::vector<const GlobalValue *> &getTypeInfos() const {
|
const std::vector<const GlobalValue *> &getTypeInfos() const {
|
||||||
return TypeInfos;
|
return TypeInfos;
|
||||||
|
|
|
@ -136,19 +136,23 @@ private:
|
||||||
/// This has to be defined eagerly due to the implementation constraints of
|
/// This has to be defined eagerly due to the implementation constraints of
|
||||||
/// `PointerSumType` where it is used.
|
/// `PointerSumType` where it is used.
|
||||||
class ExtraInfo final
|
class ExtraInfo final
|
||||||
: TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *> {
|
: TrailingObjects<ExtraInfo, MachineMemOperand *, MCSymbol *, MDNode *> {
|
||||||
public:
|
public:
|
||||||
static ExtraInfo *create(BumpPtrAllocator &Allocator,
|
static ExtraInfo *create(BumpPtrAllocator &Allocator,
|
||||||
ArrayRef<MachineMemOperand *> MMOs,
|
ArrayRef<MachineMemOperand *> MMOs,
|
||||||
MCSymbol *PreInstrSymbol = nullptr,
|
MCSymbol *PreInstrSymbol = nullptr,
|
||||||
MCSymbol *PostInstrSymbol = nullptr) {
|
MCSymbol *PostInstrSymbol = nullptr,
|
||||||
|
MDNode *HeapAllocMarker = nullptr) {
|
||||||
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
|
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
|
||||||
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
|
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
|
||||||
|
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
|
||||||
auto *Result = new (Allocator.Allocate(
|
auto *Result = new (Allocator.Allocate(
|
||||||
totalSizeToAlloc<MachineMemOperand *, MCSymbol *>(
|
totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *>(
|
||||||
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol),
|
MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
|
||||||
|
HasHeapAllocMarker),
|
||||||
alignof(ExtraInfo)))
|
alignof(ExtraInfo)))
|
||||||
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol);
|
ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
|
||||||
|
HasHeapAllocMarker);
|
||||||
|
|
||||||
// Copy the actual data into the trailing objects.
|
// Copy the actual data into the trailing objects.
|
||||||
std::copy(MMOs.begin(), MMOs.end(),
|
std::copy(MMOs.begin(), MMOs.end(),
|
||||||
|
@ -159,6 +163,8 @@ private:
|
||||||
if (HasPostInstrSymbol)
|
if (HasPostInstrSymbol)
|
||||||
Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
|
Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
|
||||||
PostInstrSymbol;
|
PostInstrSymbol;
|
||||||
|
if (HasHeapAllocMarker)
|
||||||
|
Result->getTrailingObjects<MDNode *>()[0] = HeapAllocMarker;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -177,6 +183,10 @@ private:
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MDNode *getHeapAllocMarker() const {
|
||||||
|
return HasHeapAllocMarker ? getTrailingObjects<MDNode *>()[0] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend TrailingObjects;
|
friend TrailingObjects;
|
||||||
|
|
||||||
|
@ -188,6 +198,7 @@ private:
|
||||||
const int NumMMOs;
|
const int NumMMOs;
|
||||||
const bool HasPreInstrSymbol;
|
const bool HasPreInstrSymbol;
|
||||||
const bool HasPostInstrSymbol;
|
const bool HasPostInstrSymbol;
|
||||||
|
const bool HasHeapAllocMarker;
|
||||||
|
|
||||||
// Implement the `TrailingObjects` internal API.
|
// Implement the `TrailingObjects` internal API.
|
||||||
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
|
size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
|
||||||
|
@ -196,12 +207,17 @@ private:
|
||||||
size_t numTrailingObjects(OverloadToken<MCSymbol *>) const {
|
size_t numTrailingObjects(OverloadToken<MCSymbol *>) const {
|
||||||
return HasPreInstrSymbol + HasPostInstrSymbol;
|
return HasPreInstrSymbol + HasPostInstrSymbol;
|
||||||
}
|
}
|
||||||
|
size_t numTrailingObjects(OverloadToken<MDNode *>) const {
|
||||||
|
return HasHeapAllocMarker;
|
||||||
|
}
|
||||||
|
|
||||||
// Just a boring constructor to allow us to initialize the sizes. Always use
|
// Just a boring constructor to allow us to initialize the sizes. Always use
|
||||||
// the `create` routine above.
|
// the `create` routine above.
|
||||||
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol)
|
ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
|
||||||
|
bool HasHeapAllocMarker)
|
||||||
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
|
: NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
|
||||||
HasPostInstrSymbol(HasPostInstrSymbol) {}
|
HasPostInstrSymbol(HasPostInstrSymbol),
|
||||||
|
HasHeapAllocMarker(HasHeapAllocMarker) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Enumeration of the kinds of inline extra info available. It is important
|
/// Enumeration of the kinds of inline extra info available. It is important
|
||||||
|
@ -592,6 +608,16 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper to extract a heap alloc marker if one has been added.
|
||||||
|
MDNode *getHeapAllocMarker() const {
|
||||||
|
if (!Info)
|
||||||
|
return nullptr;
|
||||||
|
if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
|
||||||
|
return EI->getHeapAllocMarker();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// API for querying MachineInstr properties. They are the same as MCInstrDesc
|
/// API for querying MachineInstr properties. They are the same as MCInstrDesc
|
||||||
/// queries but they are bundle aware.
|
/// queries but they are bundle aware.
|
||||||
|
|
||||||
|
@ -1597,6 +1623,12 @@ public:
|
||||||
/// replace ours with it.
|
/// replace ours with it.
|
||||||
void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI);
|
void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI);
|
||||||
|
|
||||||
|
/// Set a marker on instructions that denotes where we should create and emit
|
||||||
|
/// heap alloc site labels. This waits until after instruction selection and
|
||||||
|
/// optimizations to create the label, so it should still work if the
|
||||||
|
/// instruction is removed or duplicated.
|
||||||
|
void setHeapAllocMarker(MachineFunction &MF, MDNode *MD);
|
||||||
|
|
||||||
/// Return the MIFlags which represent both MachineInstrs. This
|
/// Return the MIFlags which represent both MachineInstrs. This
|
||||||
/// should be used when merging two MachineInstrs into one. This routine does
|
/// should be used when merging two MachineInstrs into one. This routine does
|
||||||
/// not modify the MIFlags of this MachineInstr.
|
/// not modify the MIFlags of this MachineInstr.
|
||||||
|
@ -1657,6 +1689,12 @@ private:
|
||||||
const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
|
const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
|
||||||
unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
|
unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
|
||||||
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
|
const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
|
||||||
|
|
||||||
|
/// Stores extra instruction information inline or allocates as ExtraInfo
|
||||||
|
/// based on the number of pointers.
|
||||||
|
void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
|
||||||
|
MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
|
||||||
|
MDNode *HeapAllocMarker);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the
|
/// Special DenseMapInfo traits to compare MachineInstr* by *value* of the
|
||||||
|
|
|
@ -1060,12 +1060,8 @@ void AsmPrinter::EmitFunctionBody() {
|
||||||
++NumInstsInFunction;
|
++NumInstsInFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a pre-instruction symbol, emit a label for it here. If the
|
// If there is a pre-instruction symbol, emit a label for it here.
|
||||||
// instruction was duplicated and the label has already been emitted,
|
|
||||||
// don't re-emit the same label.
|
|
||||||
// FIXME: Consider strengthening that to an assertion.
|
|
||||||
if (MCSymbol *S = MI.getPreInstrSymbol())
|
if (MCSymbol *S = MI.getPreInstrSymbol())
|
||||||
if (S->isUndefined())
|
|
||||||
OutStreamer->EmitLabel(S);
|
OutStreamer->EmitLabel(S);
|
||||||
|
|
||||||
if (ShouldPrintDebugScopes) {
|
if (ShouldPrintDebugScopes) {
|
||||||
|
@ -1119,12 +1115,8 @@ void AsmPrinter::EmitFunctionBody() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a post-instruction symbol, emit a label for it here. If
|
// If there is a post-instruction symbol, emit a label for it here.
|
||||||
// the instruction was duplicated and the label has already been emitted,
|
|
||||||
// don't re-emit the same label.
|
|
||||||
// FIXME: Consider strengthening that to an assertion.
|
|
||||||
if (MCSymbol *S = MI.getPostInstrSymbol())
|
if (MCSymbol *S = MI.getPostInstrSymbol())
|
||||||
if (S->isUndefined())
|
|
||||||
OutStreamer->EmitLabel(S);
|
OutStreamer->EmitLabel(S);
|
||||||
|
|
||||||
if (ShouldPrintDebugScopes) {
|
if (ShouldPrintDebugScopes) {
|
||||||
|
|
|
@ -1100,14 +1100,8 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto HeapAllocSite : FI.HeapAllocSites) {
|
for (auto HeapAllocSite : FI.HeapAllocSites) {
|
||||||
MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
|
const MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
|
||||||
MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
|
const MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
|
||||||
|
|
||||||
// The labels might not be defined if the instruction was replaced
|
|
||||||
// somewhere in the codegen pipeline.
|
|
||||||
if (!BeginLabel->isDefined() || !EndLabel->isDefined())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const DIType *DITy = std::get<2>(HeapAllocSite);
|
const DIType *DITy = std::get<2>(HeapAllocSite);
|
||||||
MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
|
MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
|
||||||
OS.AddComment("Call site offset");
|
OS.AddComment("Call site offset");
|
||||||
|
@ -1427,6 +1421,16 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
|
||||||
DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
|
DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
|
||||||
maybeRecordLocation(FnStartDL, MF);
|
maybeRecordLocation(FnStartDL, MF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find heap alloc sites and emit labels around them.
|
||||||
|
for (const auto &MBB : *MF) {
|
||||||
|
for (const auto &MI : MBB) {
|
||||||
|
if (MI.getHeapAllocMarker()) {
|
||||||
|
requestLabelBeforeInsn(&MI);
|
||||||
|
requestLabelAfterInsn(&MI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool shouldEmitUdt(const DIType *T) {
|
static bool shouldEmitUdt(const DIType *T) {
|
||||||
|
@ -2850,8 +2854,18 @@ void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find heap alloc sites and add to list.
|
||||||
|
for (const auto &MBB : *MF) {
|
||||||
|
for (const auto &MI : MBB) {
|
||||||
|
if (MDNode *MD = MI.getHeapAllocMarker()) {
|
||||||
|
CurFn->HeapAllocSites.push_back(std::make_tuple(getLabelBeforeInsn(&MI),
|
||||||
|
getLabelAfterInsn(&MI),
|
||||||
|
dyn_cast<DIType>(MD)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CurFn->Annotations = MF->getCodeViewAnnotations();
|
CurFn->Annotations = MF->getCodeViewAnnotations();
|
||||||
CurFn->HeapAllocSites = MF->getCodeViewHeapAllocSites();
|
|
||||||
|
|
||||||
CurFn->End = Asm->getFunctionEnd();
|
CurFn->End = Asm->getFunctionEnd();
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
|
||||||
SmallVector<LexicalBlock *, 1> ChildBlocks;
|
SmallVector<LexicalBlock *, 1> ChildBlocks;
|
||||||
|
|
||||||
std::vector<std::pair<MCSymbol *, MDNode *>> Annotations;
|
std::vector<std::pair<MCSymbol *, MDNode *>> Annotations;
|
||||||
std::vector<std::tuple<MCSymbol *, MCSymbol *, const DIType *>>
|
std::vector<std::tuple<const MCSymbol *, const MCSymbol *, const DIType *>>
|
||||||
HeapAllocSites;
|
HeapAllocSites;
|
||||||
|
|
||||||
const MCSymbol *Begin = nullptr;
|
const MCSymbol *Begin = nullptr;
|
||||||
|
|
|
@ -447,12 +447,11 @@ MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
|
||||||
MMO->getOrdering(), MMO->getFailureOrdering());
|
MMO->getOrdering(), MMO->getFailureOrdering());
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr::ExtraInfo *
|
MachineInstr::ExtraInfo *MachineFunction::createMIExtraInfo(
|
||||||
MachineFunction::createMIExtraInfo(ArrayRef<MachineMemOperand *> MMOs,
|
ArrayRef<MachineMemOperand *> MMOs, MCSymbol *PreInstrSymbol,
|
||||||
MCSymbol *PreInstrSymbol,
|
MCSymbol *PostInstrSymbol, MDNode *HeapAllocMarker) {
|
||||||
MCSymbol *PostInstrSymbol) {
|
|
||||||
return MachineInstr::ExtraInfo::create(Allocator, MMOs, PreInstrSymbol,
|
return MachineInstr::ExtraInfo::create(Allocator, MMOs, PreInstrSymbol,
|
||||||
PostInstrSymbol);
|
PostInstrSymbol, HeapAllocMarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *MachineFunction::createExternalSymbolName(StringRef Name) {
|
const char *MachineFunction::createExternalSymbolName(StringRef Name) {
|
||||||
|
@ -824,17 +823,6 @@ try_next:;
|
||||||
return FilterID;
|
return FilterID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineFunction::addCodeViewHeapAllocSite(MachineInstr *I,
|
|
||||||
const MDNode *MD) {
|
|
||||||
MCSymbol *BeginLabel = Ctx.createTempSymbol("heapallocsite", true);
|
|
||||||
MCSymbol *EndLabel = Ctx.createTempSymbol("heapallocsite", true);
|
|
||||||
I->setPreInstrSymbol(*this, BeginLabel);
|
|
||||||
I->setPostInstrSymbol(*this, EndLabel);
|
|
||||||
|
|
||||||
const DIType *DI = dyn_cast<DIType>(MD);
|
|
||||||
CodeViewHeapAllocSites.push_back(std::make_tuple(BeginLabel, EndLabel, DI));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachineFunction::moveCallSiteInfo(const MachineInstr *Old,
|
void MachineFunction::moveCallSiteInfo(const MachineInstr *Old,
|
||||||
const MachineInstr *New) {
|
const MachineInstr *New) {
|
||||||
assert(New->isCall() && "Call site info refers only to call instructions!");
|
assert(New->isCall() && "Call site info refers only to call instructions!");
|
||||||
|
|
|
@ -316,27 +316,48 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {
|
||||||
--NumOperands;
|
--NumOperands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MachineInstr::setExtraInfo(MachineFunction &MF,
|
||||||
|
ArrayRef<MachineMemOperand *> MMOs,
|
||||||
|
MCSymbol *PreInstrSymbol,
|
||||||
|
MCSymbol *PostInstrSymbol,
|
||||||
|
MDNode *HeapAllocMarker) {
|
||||||
|
bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
|
||||||
|
bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
|
||||||
|
bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
|
||||||
|
int NumPointers =
|
||||||
|
MMOs.size() + HasPreInstrSymbol + HasPostInstrSymbol + HasHeapAllocMarker;
|
||||||
|
|
||||||
|
// Drop all extra info if there is none.
|
||||||
|
if (NumPointers <= 0) {
|
||||||
|
Info.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If more than one pointer, then store out of line. Store heap alloc markers
|
||||||
|
// out of line because PointerSumType cannot hold more than 4 tag types with
|
||||||
|
// 32-bit pointers.
|
||||||
|
// FIXME: Maybe we should make the symbols in the extra info mutable?
|
||||||
|
else if (NumPointers > 1 || HasHeapAllocMarker) {
|
||||||
|
Info.set<EIIK_OutOfLine>(MF.createMIExtraInfo(
|
||||||
|
MMOs, PreInstrSymbol, PostInstrSymbol, HeapAllocMarker));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise store the single pointer inline.
|
||||||
|
if (HasPreInstrSymbol)
|
||||||
|
Info.set<EIIK_PreInstrSymbol>(PreInstrSymbol);
|
||||||
|
else if (HasPostInstrSymbol)
|
||||||
|
Info.set<EIIK_PostInstrSymbol>(PostInstrSymbol);
|
||||||
|
else
|
||||||
|
Info.set<EIIK_MMO>(MMOs[0]);
|
||||||
|
}
|
||||||
|
|
||||||
void MachineInstr::dropMemRefs(MachineFunction &MF) {
|
void MachineInstr::dropMemRefs(MachineFunction &MF) {
|
||||||
if (memoperands_empty())
|
if (memoperands_empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// See if we can just drop all of our extra info.
|
setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(),
|
||||||
if (!getPreInstrSymbol() && !getPostInstrSymbol()) {
|
getHeapAllocMarker());
|
||||||
Info.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!getPostInstrSymbol()) {
|
|
||||||
Info.set<EIIK_PreInstrSymbol>(getPreInstrSymbol());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!getPreInstrSymbol()) {
|
|
||||||
Info.set<EIIK_PostInstrSymbol>(getPostInstrSymbol());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise allocate a fresh extra info with just these symbols.
|
|
||||||
Info.set<EIIK_OutOfLine>(
|
|
||||||
MF.createMIExtraInfo({}, getPreInstrSymbol(), getPostInstrSymbol()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineInstr::setMemRefs(MachineFunction &MF,
|
void MachineInstr::setMemRefs(MachineFunction &MF,
|
||||||
|
@ -346,15 +367,8 @@ void MachineInstr::setMemRefs(MachineFunction &MF,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to store a single MMO inline.
|
setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(),
|
||||||
if (MMOs.size() == 1 && !getPreInstrSymbol() && !getPostInstrSymbol()) {
|
getHeapAllocMarker());
|
||||||
Info.set<EIIK_MMO>(MMOs[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise create an extra info struct with all of our info.
|
|
||||||
Info.set<EIIK_OutOfLine>(
|
|
||||||
MF.createMIExtraInfo(MMOs, getPreInstrSymbol(), getPostInstrSymbol()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineInstr::addMemOperand(MachineFunction &MF,
|
void MachineInstr::addMemOperand(MachineFunction &MF,
|
||||||
|
@ -376,7 +390,8 @@ void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {
|
||||||
// instruction. We can do this whenever the pre- and post-instruction symbols
|
// instruction. We can do this whenever the pre- and post-instruction symbols
|
||||||
// are the same (including null).
|
// are the same (including null).
|
||||||
if (getPreInstrSymbol() == MI.getPreInstrSymbol() &&
|
if (getPreInstrSymbol() == MI.getPreInstrSymbol() &&
|
||||||
getPostInstrSymbol() == MI.getPostInstrSymbol()) {
|
getPostInstrSymbol() == MI.getPostInstrSymbol() &&
|
||||||
|
getHeapAllocMarker() == MI.getHeapAllocMarker()) {
|
||||||
Info = MI.Info;
|
Info = MI.Info;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -450,67 +465,42 @@ void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
|
void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
|
||||||
MCSymbol *OldSymbol = getPreInstrSymbol();
|
// Do nothing if old and new symbols are the same.
|
||||||
if (OldSymbol == Symbol)
|
if (Symbol == getPreInstrSymbol())
|
||||||
return;
|
return;
|
||||||
if (OldSymbol && !Symbol) {
|
|
||||||
// We're removing a symbol rather than adding one. Try to clean up any
|
// If there was only one symbol and we're removing it, just clear info.
|
||||||
// extra info carried around.
|
if (!Symbol && Info.is<EIIK_PreInstrSymbol>()) {
|
||||||
if (Info.is<EIIK_PreInstrSymbol>()) {
|
|
||||||
Info.clear();
|
Info.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memoperands_empty()) {
|
setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(),
|
||||||
assert(getPostInstrSymbol() &&
|
getHeapAllocMarker());
|
||||||
"Should never have only a single symbol allocated out-of-line!");
|
|
||||||
Info.set<EIIK_PostInstrSymbol>(getPostInstrSymbol());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise fallback on the generic update.
|
|
||||||
} else if (!Info || Info.is<EIIK_PreInstrSymbol>()) {
|
|
||||||
// If we don't have any other extra info, we can store this inline.
|
|
||||||
Info.set<EIIK_PreInstrSymbol>(Symbol);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, allocate a full new set of extra info.
|
|
||||||
// FIXME: Maybe we should make the symbols in the extra info mutable?
|
|
||||||
Info.set<EIIK_OutOfLine>(
|
|
||||||
MF.createMIExtraInfo(memoperands(), Symbol, getPostInstrSymbol()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
|
void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
|
||||||
MCSymbol *OldSymbol = getPostInstrSymbol();
|
// Do nothing if old and new symbols are the same.
|
||||||
if (OldSymbol == Symbol)
|
if (Symbol == getPostInstrSymbol())
|
||||||
return;
|
return;
|
||||||
if (OldSymbol && !Symbol) {
|
|
||||||
// We're removing a symbol rather than adding one. Try to clean up any
|
// If there was only one symbol and we're removing it, just clear info.
|
||||||
// extra info carried around.
|
if (!Symbol && Info.is<EIIK_PostInstrSymbol>()) {
|
||||||
if (Info.is<EIIK_PostInstrSymbol>()) {
|
|
||||||
Info.clear();
|
Info.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memoperands_empty()) {
|
setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol,
|
||||||
assert(getPreInstrSymbol() &&
|
getHeapAllocMarker());
|
||||||
"Should never have only a single symbol allocated out-of-line!");
|
}
|
||||||
Info.set<EIIK_PreInstrSymbol>(getPreInstrSymbol());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise fallback on the generic update.
|
void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {
|
||||||
} else if (!Info || Info.is<EIIK_PostInstrSymbol>()) {
|
// Do nothing if old and new symbols are the same.
|
||||||
// If we don't have any other extra info, we can store this inline.
|
if (Marker == getHeapAllocMarker())
|
||||||
Info.set<EIIK_PostInstrSymbol>(Symbol);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, allocate a full new set of extra info.
|
setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
|
||||||
// FIXME: Maybe we should make the symbols in the extra info mutable?
|
Marker);
|
||||||
Info.set<EIIK_OutOfLine>(
|
|
||||||
MF.createMIExtraInfo(memoperands(), getPreInstrSymbol(), Symbol));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
|
void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
|
||||||
|
@ -524,6 +514,7 @@ void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
|
||||||
|
|
||||||
setPreInstrSymbol(MF, MI.getPreInstrSymbol());
|
setPreInstrSymbol(MF, MI.getPreInstrSymbol());
|
||||||
setPostInstrSymbol(MF, MI.getPostInstrSymbol());
|
setPostInstrSymbol(MF, MI.getPostInstrSymbol());
|
||||||
|
setHeapAllocMarker(MF, MI.getHeapAllocMarker());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
|
uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
|
||||||
|
@ -1710,6 +1701,13 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
|
||||||
OS << " post-instr-symbol ";
|
OS << " post-instr-symbol ";
|
||||||
MachineOperand::printSymbol(OS, *PostInstrSymbol);
|
MachineOperand::printSymbol(OS, *PostInstrSymbol);
|
||||||
}
|
}
|
||||||
|
if (MDNode *HeapAllocMarker = getHeapAllocMarker()) {
|
||||||
|
if (!FirstOp) {
|
||||||
|
FirstOp = false;
|
||||||
|
OS << ',';
|
||||||
|
}
|
||||||
|
OS << " heap-alloc-marker";
|
||||||
|
}
|
||||||
|
|
||||||
if (!SkipDebugLoc) {
|
if (!SkipDebugLoc) {
|
||||||
if (const DebugLoc &DL = getDebugLoc()) {
|
if (const DebugLoc &DL = getDebugLoc()) {
|
||||||
|
|
|
@ -1238,10 +1238,9 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) {
|
||||||
updateValueMap(CLI.CS->getInstruction(), CLI.ResultReg, CLI.NumResultRegs);
|
updateValueMap(CLI.CS->getInstruction(), CLI.ResultReg, CLI.NumResultRegs);
|
||||||
|
|
||||||
// Set labels for heapallocsite call.
|
// Set labels for heapallocsite call.
|
||||||
if (CLI.CS && CLI.CS->getInstruction()->hasMetadata("heapallocsite")) {
|
if (CLI.CS)
|
||||||
const MDNode *MD = CLI.CS->getInstruction()->getMetadata("heapallocsite");
|
if (MDNode *MD = CLI.CS->getInstruction()->getMetadata("heapallocsite"))
|
||||||
MF->addCodeViewHeapAllocSite(CLI.Call, MD);
|
CLI.Call->setHeapAllocMarker(*MF, MD);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -910,10 +910,9 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
|
||||||
if (HasDbg)
|
if (HasDbg)
|
||||||
ProcessSourceNode(N, DAG, Emitter, VRBaseMap, Orders, Seen, NewInsn);
|
ProcessSourceNode(N, DAG, Emitter, VRBaseMap, Orders, Seen, NewInsn);
|
||||||
|
|
||||||
if (MDNode *MD = DAG->getHeapAllocSite(N)) {
|
if (MDNode *MD = DAG->getHeapAllocSite(N))
|
||||||
if (NewInsn && NewInsn->isCall())
|
if (NewInsn && NewInsn->isCall())
|
||||||
MF.addCodeViewHeapAllocSite(NewInsn, MD);
|
NewInsn->setHeapAllocMarker(MF, MD);
|
||||||
}
|
|
||||||
|
|
||||||
GluedNodes.pop_back();
|
GluedNodes.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -923,9 +922,10 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
|
||||||
if (HasDbg)
|
if (HasDbg)
|
||||||
ProcessSourceNode(SU->getNode(), DAG, Emitter, VRBaseMap, Orders, Seen,
|
ProcessSourceNode(SU->getNode(), DAG, Emitter, VRBaseMap, Orders, Seen,
|
||||||
NewInsn);
|
NewInsn);
|
||||||
|
|
||||||
if (MDNode *MD = DAG->getHeapAllocSite(SU->getNode())) {
|
if (MDNode *MD = DAG->getHeapAllocSite(SU->getNode())) {
|
||||||
if (NewInsn && NewInsn->isCall())
|
if (NewInsn && NewInsn->isCall())
|
||||||
MF.addCodeViewHeapAllocSite(NewInsn, MD);
|
NewInsn->setHeapAllocMarker(MF, MD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
; RUN: llc < %s | FileCheck --check-prefixes=DAG,CHECK %s
|
; RUN: llc < %s | FileCheck --check-prefixes=CHECK %s
|
||||||
; RUN: llc -O0 < %s | FileCheck --check-prefixes=FAST,CHECK %s
|
; RUN: llc -O0 < %s | FileCheck --check-prefixes=CHECK %s
|
||||||
|
|
||||||
; Source to regenerate:
|
; Source to regenerate:
|
||||||
; $ clang -cc1 -triple x86_64-windows-msvc t.cpp -debug-info-kind=limited \
|
; $ clang -cc1 -triple x86_64-windows-msvc t.cpp -debug-info-kind=limited \
|
||||||
|
@ -71,42 +71,33 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) #2
|
||||||
|
|
||||||
; Don't emit metadata for tail calls.
|
; Don't emit metadata for tail calls.
|
||||||
; CHECK-LABEL: call_tail: # @call_tail
|
; CHECK-LABEL: call_tail: # @call_tail
|
||||||
; CHECK-NOT: .Lheapallocsite
|
|
||||||
; CHECK: jmp alloc_foo
|
; CHECK: jmp alloc_foo
|
||||||
|
|
||||||
; CHECK-LABEL: call_virtual: # @call_virtual
|
; CHECK-LABEL: call_virtual: # @call_virtual
|
||||||
; CHECK: .Lheapallocsite0:
|
|
||||||
; CHECK: callq *{{.*}}%rax{{.*}}
|
; CHECK: callq *{{.*}}%rax{{.*}}
|
||||||
; CHECK: .Lheapallocsite1:
|
; CHECK-NEXT: [[LABEL1:.Ltmp[0-9]+]]:
|
||||||
|
|
||||||
; CHECK-LABEL: call_multiple: # @call_multiple
|
; CHECK-LABEL: call_multiple: # @call_multiple
|
||||||
; FastISel emits instructions in a different order.
|
|
||||||
; DAG: .Lheapallocsite2:
|
|
||||||
; FAST: .Lheapallocsite4:
|
|
||||||
; CHECK: callq alloc_foo
|
; CHECK: callq alloc_foo
|
||||||
; DAG: .Lheapallocsite3:
|
; CHECK-NEXT: [[LABEL3:.Ltmp[0-9]+]]:
|
||||||
; FAST: .Lheapallocsite5:
|
|
||||||
; DAG: .Lheapallocsite4:
|
|
||||||
; FAST: .Lheapallocsite2:
|
|
||||||
; CHECK: callq alloc_foo
|
; CHECK: callq alloc_foo
|
||||||
; DAG: .Lheapallocsite5:
|
; CHECK-NEXT: [[LABEL5:.Ltmp[0-9]+]]:
|
||||||
; FAST: .Lheapallocsite3:
|
|
||||||
|
|
||||||
; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
|
; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
|
||||||
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
||||||
; CHECK-NEXT: .secrel32 .Lheapallocsite0
|
; CHECK-NEXT: .secrel32 [[LABEL0:.Ltmp[0-9]+]]
|
||||||
; CHECK-NEXT: .secidx .Lheapallocsite0
|
; CHECK-NEXT: .secidx [[LABEL0]]
|
||||||
; CHECK-NEXT: .short .Lheapallocsite1-.Lheapallocsite0
|
; CHECK-NEXT: .short [[LABEL1]]-[[LABEL0]]
|
||||||
; CHECK-NEXT: .long 3
|
; CHECK-NEXT: .long 3
|
||||||
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
||||||
; CHECK-NEXT: .secrel32 .Lheapallocsite2
|
; CHECK-NEXT: .secrel32 [[LABEL2:.Ltmp[0-9]+]]
|
||||||
; CHECK-NEXT: .secidx .Lheapallocsite2
|
; CHECK-NEXT: .secidx [[LABEL2]]
|
||||||
; CHECK-NEXT: .short .Lheapallocsite3-.Lheapallocsite2
|
; CHECK-NEXT: .short [[LABEL3]]-[[LABEL2]]
|
||||||
; CHECK-NEXT: .long 4096
|
; CHECK-NEXT: .long 4096
|
||||||
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
||||||
; CHECK-NEXT: .secrel32 .Lheapallocsite4
|
; CHECK-NEXT: .secrel32 [[LABEL4:.Ltmp[0-9]+]]
|
||||||
; CHECK-NEXT: .secidx .Lheapallocsite4
|
; CHECK-NEXT: .secidx [[LABEL4]]
|
||||||
; CHECK-NEXT: .short .Lheapallocsite5-.Lheapallocsite4
|
; CHECK-NEXT: .short [[LABEL5]]-[[LABEL4]]
|
||||||
; CHECK-NEXT: .long 4096
|
; CHECK-NEXT: .long 4096
|
||||||
|
|
||||||
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
; f2();
|
; f2();
|
||||||
; }
|
; }
|
||||||
|
|
||||||
; In this case, block placement duplicates the heap allocation site. For now,
|
; In this case, block placement duplicates the heap allocation site.
|
||||||
; LLVM drops the labels from one call site. Eventually, we should track both.
|
|
||||||
|
|
||||||
; ModuleID = 't.cpp'
|
; ModuleID = 't.cpp'
|
||||||
source_filename = "t.cpp"
|
source_filename = "t.cpp"
|
||||||
|
@ -37,15 +36,25 @@ cond.end: ; preds = %entry, %cond.true
|
||||||
; CHECK-LABEL: taildupit: # @taildupit
|
; CHECK-LABEL: taildupit: # @taildupit
|
||||||
; CHECK: testq
|
; CHECK: testq
|
||||||
; CHECK: je
|
; CHECK: je
|
||||||
; CHECK: .Lheapallocsite0:
|
|
||||||
; CHECK: callq alloc
|
; CHECK: callq alloc
|
||||||
; CHECK: .Lheapallocsite1:
|
; CHECK-NEXT: [[L1:.Ltmp[0-9]+]]
|
||||||
; CHECK: jmp f2 # TAILCALL
|
; CHECK: jmp f2 # TAILCALL
|
||||||
; CHECK-NOT: Lheapallocsite
|
|
||||||
; CHECK: callq alloc
|
; CHECK: callq alloc
|
||||||
; CHECK-NOT: Lheapallocsite
|
; CHECK-NEXT: [[L3:.Ltmp[0-9]+]]
|
||||||
; CHECK: jmp f2 # TAILCALL
|
; CHECK: jmp f2 # TAILCALL
|
||||||
|
|
||||||
|
; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
|
||||||
|
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
||||||
|
; CHECK-NEXT: .secrel32 [[L0:.Ltmp[0-9]+]]
|
||||||
|
; CHECK-NEXT: .secidx [[L0]]
|
||||||
|
; CHECK-NEXT: .short [[L1]]-[[L0]]
|
||||||
|
; CHECK-NEXT: .long 3
|
||||||
|
; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
|
||||||
|
; CHECK-NEXT: .secrel32 [[L2:.Ltmp[0-9]+]]
|
||||||
|
; CHECK-NEXT: .secidx [[L2]]
|
||||||
|
; CHECK-NEXT: .short [[L3]]-[[L2]]
|
||||||
|
; CHECK-NEXT: .long 3
|
||||||
|
|
||||||
declare dso_local i8* @alloc(i32)
|
declare dso_local i8* @alloc(i32)
|
||||||
|
|
||||||
declare dso_local void @f2()
|
declare dso_local void @f2()
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
#include "llvm/CodeGen/TargetFrameLowering.h"
|
#include "llvm/CodeGen/TargetFrameLowering.h"
|
||||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||||
|
@ -16,6 +17,8 @@
|
||||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||||
#include "llvm/IR/DebugInfoMetadata.h"
|
#include "llvm/IR/DebugInfoMetadata.h"
|
||||||
#include "llvm/IR/ModuleSlotTracker.h"
|
#include "llvm/IR/ModuleSlotTracker.h"
|
||||||
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
@ -125,6 +128,7 @@ public:
|
||||||
: LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(),
|
: LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(),
|
||||||
Reloc::Static, CodeModel::Small, CodeGenOpt::Default),
|
Reloc::Static, CodeModel::Small, CodeGenOpt::Default),
|
||||||
ST(*this) {}
|
ST(*this) {}
|
||||||
|
|
||||||
~BogusTargetMachine() override {}
|
~BogusTargetMachine() override {}
|
||||||
|
|
||||||
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
|
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
|
||||||
|
@ -135,6 +139,13 @@ private:
|
||||||
BogusSubtarget ST;
|
BogusSubtarget ST;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static MCAsmInfo AsmInfo = MCAsmInfo();
|
||||||
|
|
||||||
|
std::unique_ptr<MCContext> createMCContext() {
|
||||||
|
return std::make_unique<MCContext>(
|
||||||
|
&AsmInfo, nullptr, nullptr, nullptr, nullptr, false);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<BogusTargetMachine> createTargetMachine() {
|
std::unique_ptr<BogusTargetMachine> createTargetMachine() {
|
||||||
return std::make_unique<BogusTargetMachine>();
|
return std::make_unique<BogusTargetMachine>();
|
||||||
}
|
}
|
||||||
|
@ -361,6 +372,135 @@ TEST(MachineInstrSpan, DistanceEnd) {
|
||||||
ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
|
ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MachineInstrExtraInfo, AddExtraInfo) {
|
||||||
|
auto MF = createMachineFunction();
|
||||||
|
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0,
|
||||||
|
0, nullptr, nullptr, nullptr, 0, nullptr};
|
||||||
|
|
||||||
|
auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||||
|
auto MC = createMCContext();
|
||||||
|
auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
|
||||||
|
MachineMemOperand::MOLoad, 8, 8);
|
||||||
|
SmallVector<MachineMemOperand *, 2> MMOs;
|
||||||
|
MMOs.push_back(MMO);
|
||||||
|
MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
|
||||||
|
MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
|
||||||
|
LLVMContext Ctx;
|
||||||
|
MDNode *MDN = MDNode::getDistinct(Ctx, None);
|
||||||
|
|
||||||
|
ASSERT_TRUE(MI->memoperands_empty());
|
||||||
|
ASSERT_FALSE(MI->getPreInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
|
||||||
|
MI->setMemRefs(*MF, MMOs);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 1);
|
||||||
|
ASSERT_FALSE(MI->getPreInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
|
||||||
|
MI->setPreInstrSymbol(*MF, Sym1);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 1);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
|
||||||
|
MI->setPostInstrSymbol(*MF, Sym2);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 1);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
|
||||||
|
MI->setHeapAllocMarker(*MF, MDN);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 1);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
|
||||||
|
ASSERT_TRUE(MI->getHeapAllocMarker() == MDN);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MachineInstrExtraInfo, ChangeExtraInfo) {
|
||||||
|
auto MF = createMachineFunction();
|
||||||
|
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0,
|
||||||
|
0, nullptr, nullptr, nullptr, 0, nullptr};
|
||||||
|
|
||||||
|
auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||||
|
auto MC = createMCContext();
|
||||||
|
auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
|
||||||
|
MachineMemOperand::MOLoad, 8, 8);
|
||||||
|
SmallVector<MachineMemOperand *, 2> MMOs;
|
||||||
|
MMOs.push_back(MMO);
|
||||||
|
MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
|
||||||
|
MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
|
||||||
|
LLVMContext Ctx;
|
||||||
|
MDNode *MDN = MDNode::getDistinct(Ctx, None);
|
||||||
|
|
||||||
|
MI->setMemRefs(*MF, MMOs);
|
||||||
|
MI->setPreInstrSymbol(*MF, Sym1);
|
||||||
|
MI->setPostInstrSymbol(*MF, Sym2);
|
||||||
|
MI->setHeapAllocMarker(*MF, MDN);
|
||||||
|
|
||||||
|
MMOs.push_back(MMO);
|
||||||
|
|
||||||
|
MI->setMemRefs(*MF, MMOs);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 2);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2);
|
||||||
|
ASSERT_TRUE(MI->getHeapAllocMarker() == MDN);
|
||||||
|
|
||||||
|
MI->setPostInstrSymbol(*MF, Sym1);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 2);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1);
|
||||||
|
ASSERT_TRUE(MI->getHeapAllocMarker() == MDN);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MachineInstrExtraInfo, RemoveExtraInfo) {
|
||||||
|
auto MF = createMachineFunction();
|
||||||
|
MCInstrDesc MCID = {0, 0, 0, 0, 0, 0,
|
||||||
|
0, nullptr, nullptr, nullptr, 0, nullptr};
|
||||||
|
|
||||||
|
auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
|
||||||
|
auto MC = createMCContext();
|
||||||
|
auto MMO = MF->getMachineMemOperand(MachinePointerInfo(),
|
||||||
|
MachineMemOperand::MOLoad, 8, 8);
|
||||||
|
SmallVector<MachineMemOperand *, 2> MMOs;
|
||||||
|
MMOs.push_back(MMO);
|
||||||
|
MMOs.push_back(MMO);
|
||||||
|
MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false);
|
||||||
|
MCSymbol *Sym2 = MC->createTempSymbol("post_label", false);
|
||||||
|
LLVMContext Ctx;
|
||||||
|
MDNode *MDN = MDNode::getDistinct(Ctx, None);
|
||||||
|
|
||||||
|
MI->setMemRefs(*MF, MMOs);
|
||||||
|
MI->setPreInstrSymbol(*MF, Sym1);
|
||||||
|
MI->setPostInstrSymbol(*MF, Sym2);
|
||||||
|
MI->setHeapAllocMarker(*MF, MDN);
|
||||||
|
|
||||||
|
MI->setPostInstrSymbol(*MF, nullptr);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 2);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_TRUE(MI->getHeapAllocMarker() == MDN);
|
||||||
|
|
||||||
|
MI->setHeapAllocMarker(*MF, nullptr);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 2);
|
||||||
|
ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1);
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
|
||||||
|
MI->setPreInstrSymbol(*MF, nullptr);
|
||||||
|
ASSERT_TRUE(MI->memoperands().size() == 2);
|
||||||
|
ASSERT_FALSE(MI->getPreInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
|
||||||
|
MI->setMemRefs(*MF, {});
|
||||||
|
ASSERT_TRUE(MI->memoperands_empty());
|
||||||
|
ASSERT_FALSE(MI->getPreInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getPostInstrSymbol());
|
||||||
|
ASSERT_FALSE(MI->getHeapAllocMarker());
|
||||||
|
}
|
||||||
|
|
||||||
static_assert(is_trivially_copyable<MCOperand>::value, "trivially copyable");
|
static_assert(is_trivially_copyable<MCOperand>::value, "trivially copyable");
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
Loading…
Reference in New Issue