aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp4
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp107
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h35
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp32
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h4
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfFile.h9
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp13
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h16
-rw-r--r--llvm/lib/CodeGen/LexicalScopes.cpp33
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp2
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp2
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp20
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp22
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp12
15 files changed, 211 insertions, 102 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 0f3ff98..d98d180 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -105,6 +105,8 @@ DebugHandlerBase::~DebugHandlerBase() = default;
void DebugHandlerBase::beginModule(Module *M) {
if (M->debug_compile_units().empty())
Asm = nullptr;
+ else
+ LScopes.initialize(*M);
}
// Each LexicalScope has first instruction and last instruction to mark
@@ -269,7 +271,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
// Grab the lexical scopes for the function, if we don't have any of those
// then we're not going to be able to do anything.
- LScopes.initialize(*MF);
+ LScopes.scanFunction(*MF);
if (LScopes.empty()) {
beginFunctionImpl(MF);
return;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 67f526f..518121e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -537,8 +537,9 @@ void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
// and DW_AT_high_pc attributes. If there are global variables in this
// scope then create and insert DIEs for these variables.
DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP,
+ const Function &F,
MCSymbol *LineTableSym) {
- DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
+ DIE *SPDie = getOrCreateSubprogramDIE(SP, &F, includeMinimalInlineScopes());
SmallVector<RangeSpan, 2> BB_List;
// If basic block sections are on, ranges for each basic block section has
// to be emitted separately.
@@ -1122,9 +1123,10 @@ sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
}
DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
+ const Function &F,
LexicalScope *Scope,
MCSymbol *LineTableSym) {
- DIE &ScopeDIE = updateSubprogramScopeDIE(Sub, LineTableSym);
+ DIE &ScopeDIE = updateSubprogramScopeDIE(Sub, F, LineTableSym);
if (Scope) {
assert(!Scope->getInlinedAt());
@@ -1198,32 +1200,17 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
return ObjectPointer;
}
-void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
- LexicalScope *Scope) {
- auto *SP = cast<DISubprogram>(Scope->getScopeNode());
- if (getAbstractScopeDIEs().count(SP))
- return;
+DIE &DwarfCompileUnit::getOrCreateAbstractSubprogramDIE(
+ const DISubprogram *SP) {
+ if (auto *AbsDef = getAbstractScopeDIEs().lookup(SP))
+ return *AbsDef;
- DIE *ContextDIE;
- DwarfCompileUnit *ContextCU = this;
-
- if (includeMinimalInlineScopes())
- ContextDIE = &getUnitDie();
- // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
- // the important distinction that the debug node is not associated with the
- // DIE (since the debug node will be associated with the concrete DIE, if
- // any). It could be refactored to some common utility function.
- else if (auto *SPDecl = SP->getDeclaration()) {
- ContextDIE = &getUnitDie();
- getOrCreateSubprogramDIE(SPDecl);
- } else {
- ContextDIE = getOrCreateContextDIE(SP->getScope());
- // The scope may be shared with a subprogram that has already been
- // constructed in another CU, in which case we need to construct this
- // subprogram in the same CU.
- ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
- }
+ auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);
+ return createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);
+}
+DIE &DwarfCompileUnit::createAbstractSubprogramDIE(
+ const DISubprogram *SP, DIE *ContextDIE, DwarfCompileUnit *ContextCU) {
// Passing null as the associated node because the abstract definition
// shouldn't be found by lookup.
DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
@@ -1237,8 +1224,45 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()
: dwarf::DW_FORM_implicit_const,
dwarf::DW_INL_inlined);
- if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef))
- ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
+
+ return AbsDef;
+}
+
+std::pair<DIE *, DwarfCompileUnit *>
+DwarfCompileUnit::getOrCreateAbstractSubprogramContextDIE(
+ const DISubprogram *SP) {
+ bool Minimal = includeMinimalInlineScopes();
+ bool IgnoreScope = shouldPlaceInUnitDIE(SP, Minimal);
+ DIE *ContextDIE = getOrCreateSubprogramContextDIE(SP, IgnoreScope);
+
+ if (auto *SPDecl = SP->getDeclaration())
+ if (!Minimal)
+ getOrCreateSubprogramDIE(SPDecl, nullptr);
+
+ // The scope may be shared with a subprogram that has already been
+ // constructed in another CU, in which case we need to construct this
+ // subprogram in the same CU.
+ auto *ContextCU = IgnoreScope ? this : DD->lookupCU(ContextDIE->getUnitDie());
+
+ return std::make_pair(ContextDIE, ContextCU);
+}
+
+void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
+ LexicalScope *Scope) {
+ auto *SP = cast<DISubprogram>(Scope->getScopeNode());
+
+ // Populate subprogram DIE only once.
+ if (!getFinalizedAbstractSubprograms().insert(SP).second)
+ return;
+
+ auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);
+ DIE *AbsDef = getAbstractScopeDIEs().lookup(SP);
+ if (!AbsDef)
+ AbsDef = &createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);
+
+ if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
+ ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer,
+ *ObjectPointer);
}
bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
@@ -1293,9 +1317,9 @@ DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
}
DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
- DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail,
- const MCSymbol *PCAddr, const MCSymbol *CallAddr, unsigned CallReg,
- DIType *AllocSiteTy) {
+ DIE &ScopeDIE, const DISubprogram *CalleeSP, const Function *CalleeF,
+ bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr,
+ unsigned CallReg, DIType *AllocSiteTy) {
// Insert a call site entry DIE within ScopeDIE.
DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
ScopeDIE, nullptr);
@@ -1305,7 +1329,7 @@ DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
MachineLocation(CallReg));
} else if (CalleeSP) {
- DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
+ DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP, CalleeF);
assert(CalleeDIE && "Could not create DIE for call site entry origin");
if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&
!CalleeSP->isDefinition() &&
@@ -1396,7 +1420,7 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))
EntityDie = AbsSPDie;
else
- EntityDie = getOrCreateSubprogramDIE(SP);
+ EntityDie = getOrCreateSubprogramDIE(SP, nullptr);
} else if (auto *T = dyn_cast<DIType>(Entity))
EntityDie = getOrCreateTypeDIE(T);
else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
@@ -1805,3 +1829,20 @@ DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {
}
return DwarfUnit::getOrCreateContextDIE(Context);
}
+
+DIE *DwarfCompileUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
+ const Function *F,
+ bool Minimal) {
+ if (!F && SP->isDefinition()) {
+ F = DD->getLexicalScopes().getFunction(SP);
+
+ if (!F) {
+ // SP may belong to another CU. Determine the CU similarly
+ // to DwarfDebug::constructAbstractSubprogramScopeDIE.
+ return &DD->getOrCreateAbstractSubprogramCU(SP, *this)
+ .getOrCreateAbstractSubprogramDIE(SP);
+ }
+ }
+
+ return DwarfUnit::getOrCreateSubprogramDIE(SP, F, Minimal);
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index c2f6ca0..a3bbc83 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -81,6 +81,7 @@ class DwarfCompileUnit final : public DwarfUnit {
// List of abstract local scopes (either DISubprogram or DILexicalBlock).
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
+ SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
// List of inlined lexical block scopes that belong to subprograms within this
// CU.
@@ -137,12 +138,28 @@ class DwarfCompileUnit final : public DwarfUnit {
return DU->getAbstractEntities();
}
+ auto &getFinalizedAbstractSubprograms() {
+ if (isDwoUnit() && !DD->shareAcrossDWOCUs())
+ return FinalizedAbstractSubprograms;
+ return DU->getFinalizedAbstractSubprograms();
+ }
+
void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;
/// Add info for Wasm-global-based relocation.
void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
uint64_t GlobalIndex);
+ /// Create context DIE for abstract subprogram.
+ /// \returns The context DIE and the compile unit where abstract
+ /// DIE should be constructed.
+ std::pair<DIE *, DwarfCompileUnit *>
+ getOrCreateAbstractSubprogramContextDIE(const DISubprogram *SP);
+
+ /// Create new DIE for abstract subprogram.
+ DIE &createAbstractSubprogramDIE(const DISubprogram *SP, DIE *ContextDIE,
+ DwarfCompileUnit *ContextCU);
+
public:
DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU,
@@ -216,7 +233,8 @@ public:
/// DW_AT_low_pc, DW_AT_high_pc and DW_AT_LLVM_stmt_sequence attributes.
/// If there are global variables in this scope then create and insert DIEs
/// for these variables.
- DIE &updateSubprogramScopeDIE(const DISubprogram *SP, MCSymbol *LineTableSym);
+ DIE &updateSubprogramScopeDIE(const DISubprogram *SP, const Function &F,
+ MCSymbol *LineTableSym);
void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);
@@ -259,12 +277,18 @@ public:
/// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.
DIE *getOrCreateContextDIE(const DIScope *Ty) override;
+ DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, const Function *F,
+ bool Minimal = false) override;
+
/// Construct a DIE for this subprogram scope.
- DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope,
- MCSymbol *LineTableSym);
+ DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F,
+ LexicalScope *Scope, MCSymbol *LineTableSym);
DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE);
+ /// Create an abstract subprogram DIE, that should later be populated
+ /// by \ref constructAbstractSubprogramScopeDIE.
+ DIE &getOrCreateAbstractSubprogramDIE(const DISubprogram *SP);
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
/// Whether to use the GNU analog for a DWARF5 tag, attribute, or location
@@ -281,14 +305,15 @@ public:
dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const;
/// Construct a call site entry DIE describing a call within \p Scope to a
- /// callee described by \p CalleeSP.
+ /// callee described by \p CalleeSP and \p CalleeF.
/// \p IsTail specifies whether the call is a tail call.
/// \p PCAddr points to the PC value after the call instruction.
/// \p CallAddr points to the PC value at the call instruction (or is null).
/// \p CallReg is a register location for an indirect call. For direct calls
/// the \p CallReg is set to 0.
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
- bool IsTail, const MCSymbol *PCAddr,
+ const Function *CalleeF, bool IsTail,
+ const MCSymbol *PCAddr,
const MCSymbol *CallAddr, unsigned CallReg,
DIType *AllocSiteTy);
/// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 05d3d18..09d5f9c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -548,6 +548,16 @@ bool DwarfDebug::shareAcrossDWOCUs() const {
return SplitDwarfCrossCuReferences;
}
+DwarfCompileUnit &
+DwarfDebug::getOrCreateAbstractSubprogramCU(const DISubprogram *SP,
+ DwarfCompileUnit &SrcCU) {
+ auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
+ if (CU.getSkeleton())
+ return shareAcrossDWOCUs() ? CU : SrcCU;
+
+ return CU;
+}
+
void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
LexicalScope *Scope) {
assert(Scope && Scope->getScopeNode());
@@ -559,14 +569,11 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
// Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
// was inlined from another compile unit.
auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
- if (auto *SkelCU = CU.getSkeleton()) {
- (shareAcrossDWOCUs() ? CU : SrcCU)
- .constructAbstractSubprogramScopeDIE(Scope);
+ auto &TargetCU = getOrCreateAbstractSubprogramCU(SP, SrcCU);
+ TargetCU.constructAbstractSubprogramScopeDIE(Scope);
+ if (auto *SkelCU = CU.getSkeleton())
if (CU.getCUNode()->getSplitDebugInlining())
SkelCU->constructAbstractSubprogramScopeDIE(Scope);
- } else {
- CU.constructAbstractSubprogramScopeDIE(Scope);
- }
}
/// Represents a parameter whose call site value can be described by applying a
@@ -997,8 +1004,9 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
->getName(CallReg)))
<< (IsTail ? " [IsTail]" : "") << "\n");
- DIE &CallSiteDIE = CU.constructCallSiteEntryDIE(
- ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg, AllocSiteTy);
+ DIE &CallSiteDIE =
+ CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,
+ PCAddr, CallAddr, CallReg, AllocSiteTy);
// Optionally emit call-site-param debug info.
if (emitDebugEntryValues()) {
@@ -2707,7 +2715,8 @@ void DwarfDebug::skippedNonDebugFunction() {
// Gather and emit post-function debug information.
void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
- const DISubprogram *SP = MF->getFunction().getSubprogram();
+ const Function &F = MF->getFunction();
+ const DISubprogram *SP = F.getSubprogram();
assert(CurFn == MF &&
"endFunction should be called with the same function as beginFunction");
@@ -2776,11 +2785,12 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
ProcessedSPNodes.insert(SP);
DIE &ScopeDIE =
- TheCU.constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel);
+ TheCU.constructSubprogramScopeDIE(SP, F, FnScope, FunctionLineTableLabel);
if (auto *SkelCU = TheCU.getSkeleton())
if (!LScopes.getAbstractScopesList().empty() &&
TheCU.getCUNode()->getSplitDebugInlining())
- SkelCU->constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel);
+ SkelCU->constructSubprogramScopeDIE(SP, F, FnScope,
+ FunctionLineTableLabel);
FunctionLineTableLabel = nullptr;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 89813dc..1a1b28a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -906,6 +906,10 @@ public:
return CUDieMap.lookup(Die);
}
+ /// Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
+ DwarfCompileUnit &getOrCreateAbstractSubprogramCU(const DISubprogram *SP,
+ DwarfCompileUnit &SrcCU);
+
unsigned getStringTypeLoc(const DIStringType *ST) const {
return StringTypeLocMap.lookup(ST);
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
index 0fc2b91..ef1524d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
@@ -11,6 +11,7 @@
#include "DwarfStringPool.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DIE.h"
@@ -27,6 +28,7 @@ class DbgVariable;
class DbgLabel;
class DINode;
class DILocalScope;
+class DISubprogram;
class DwarfCompileUnit;
class DwarfUnit;
class LexicalScope;
@@ -94,6 +96,9 @@ class DwarfFile {
// Collection of abstract subprogram DIEs.
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
+ /// Keeps track of abstract subprograms to populate them only once.
+ // FIXME: merge creation and population of abstract scopes.
+ SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
/// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
/// be shared across CUs, that is why we keep the map here instead
@@ -174,6 +179,10 @@ public:
return AbstractEntities;
}
+ auto &getFinalizedAbstractSubprograms() {
+ return FinalizedAbstractSubprograms;
+ }
+
void insertDIE(const MDNode *TypeMD, DIE *Die) {
DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index d76fd0c..62fb5eb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -573,7 +573,7 @@ DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {
if (auto *NS = dyn_cast<DINamespace>(Context))
return getOrCreateNameSpace(NS);
if (auto *SP = dyn_cast<DISubprogram>(Context))
- return getOrCreateSubprogramDIE(SP);
+ return getOrCreateSubprogramDIE(SP, nullptr);
if (auto *M = dyn_cast<DIModule>(Context))
return getOrCreateModule(M);
return getDIE(Context);
@@ -1066,7 +1066,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
if (!Element)
continue;
if (auto *SP = dyn_cast<DISubprogram>(Element))
- getOrCreateSubprogramDIE(SP);
+ getOrCreateSubprogramDIE(SP, nullptr);
else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
if (DDTy->getTag() == dwarf::DW_TAG_friend) {
DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
@@ -1335,22 +1335,21 @@ DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
return &MDie;
}
-DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {
+DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
+ const Function *FnHint, bool Minimal) {
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE (as is the case for member function
// declarations).
DIE *ContextDIE =
- Minimal ? &getUnitDie() : getOrCreateContextDIE(SP->getScope());
+ getOrCreateSubprogramContextDIE(SP, shouldPlaceInUnitDIE(SP, Minimal));
if (DIE *SPDie = getDIE(SP))
return SPDie;
if (auto *SPDecl = SP->getDeclaration()) {
if (!Minimal) {
- // Add subprogram definitions to the CU die directly.
- ContextDIE = &getUnitDie();
// Build the decl now to ensure it precedes the definition.
- getOrCreateSubprogramDIE(SPDecl);
+ getOrCreateSubprogramDIE(SPDecl, nullptr);
// Check whether the DIE for SP has already been created after the call
// above.
// FIXME: Should the creation of definition subprogram DIE during
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index fe05766..bb00ec3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -256,7 +256,9 @@ public:
DIE *getOrCreateNameSpace(const DINamespace *NS);
DIE *getOrCreateModule(const DIModule *M);
- DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false);
+ virtual DIE *getOrCreateSubprogramDIE(const DISubprogram *SP,
+ const Function *FnHint,
+ bool Minimal = false);
void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
bool SkipSPAttributes = false);
@@ -343,6 +345,18 @@ protected:
/// Emit the common part of the header for this unit.
void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT);
+ bool shouldPlaceInUnitDIE(const DISubprogram *SP, bool Minimal) {
+ // Add subprogram declarations to the CU die directly.
+ return Minimal || SP->getDeclaration();
+ }
+
+ DIE *getOrCreateSubprogramContextDIE(const DISubprogram *SP,
+ bool IgnoreScope) {
+ if (IgnoreScope)
+ return &getUnitDie();
+ return getOrCreateContextDIE(SP->getScope());
+ }
+
private:
/// A helper to add a wide integer constant to a DIE using a block
/// form.
diff --git a/llvm/lib/CodeGen/LexicalScopes.cpp b/llvm/lib/CodeGen/LexicalScopes.cpp
index 5916f61..9fc9ac9 100644
--- a/llvm/lib/CodeGen/LexicalScopes.cpp
+++ b/llvm/lib/CodeGen/LexicalScopes.cpp
@@ -23,6 +23,7 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
@@ -36,8 +37,16 @@ using namespace llvm;
#define DEBUG_TYPE "lexicalscopes"
-/// reset - Reset the instance so that it's prepared for another function.
-void LexicalScopes::reset() {
+static bool skipUnit(const DICompileUnit *CU) {
+ return CU->getEmissionKind() == DICompileUnit::NoDebug;
+}
+
+void LexicalScopes::resetModule() {
+ FunctionMap.clear();
+ resetFunction();
+}
+
+void LexicalScopes::resetFunction() {
MF = nullptr;
CurrentFnLexicalScope = nullptr;
LexicalScopeMap.clear();
@@ -47,12 +56,19 @@ void LexicalScopes::reset() {
DominatedBlocks.clear();
}
-/// initialize - Scan machine function and constuct lexical scope nest.
-void LexicalScopes::initialize(const MachineFunction &Fn) {
- reset();
+void LexicalScopes::initialize(const Module &M) {
+ resetModule();
+ for (const Function &F : M) {
+ DISubprogram *SP = F.getSubprogram();
+ if (SP && (!SP->getUnit() || !skipUnit(SP->getUnit())))
+ FunctionMap[SP] = &F;
+ }
+}
+
+void LexicalScopes::scanFunction(const MachineFunction &Fn) {
+ resetFunction();
// Don't attempt any lexical scope creation for a NoDebug compile unit.
- if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
- DICompileUnit::NoDebug)
+ if (skipUnit(Fn.getFunction().getSubprogram()->getUnit()))
return;
MF = &Fn;
SmallVector<InsnRange, 4> MIRanges;
@@ -143,8 +159,7 @@ LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
const DILocation *IA) {
if (IA) {
// Skip scopes inlined from a NoDebug compile unit.
- if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
- DICompileUnit::NoDebug)
+ if (skipUnit(Scope->getSubprogram()->getUnit()))
return getOrCreateLexicalScope(IA);
// Create an abstract scope for inlined function.
getOrCreateAbstractScope(Scope);
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index a8143bd..0037bdd 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -3721,7 +3721,7 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
TFI = MF.getSubtarget().getFrameLowering();
TFI->getCalleeSaves(MF, CalleeSavedRegs);
MFI = &MF.getFrameInfo();
- LS.initialize(MF);
+ LS.scanFunction(MF);
const auto &STI = MF.getSubtarget();
AdjustsStackInCalls = MFI->adjustsStack() &&
diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
index 82e0c28..b9ea03f 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
@@ -2231,7 +2231,7 @@ bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF,
TFI->getCalleeSaves(MF, CalleeSavedRegs);
this->ShouldEmitDebugEntryValues = ShouldEmitDebugEntryValues;
- LS.initialize(MF);
+ LS.scanFunction(MF);
bool Changed = false;
bool OLChanged = false;
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 84e9f03..001ba52 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -1263,7 +1263,7 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI,
void LiveDebugVariables::LDVImpl::computeIntervals() {
LexicalScopes LS;
- LS.initialize(*MF);
+ LS.scanFunction(*MF);
for (const auto &UV : userValues) {
UV->computeIntervals(MF->getRegInfo(), *TRI, *LIS, LS);
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index e911ce8..1154855 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1549,7 +1549,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
report("G_BUILD_VECTOR result element type must match source type", MI);
if (DstTy.getNumElements() != MI->getNumOperands() - 1)
- report("G_BUILD_VECTOR must have an operand for each elemement", MI);
+ report("G_BUILD_VECTOR must have an operand for each element", MI);
for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 2))
if (MRI->getType(MI->getOperand(1).getReg()) != MRI->getType(MO.getReg()))
@@ -2398,11 +2398,11 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
// The next two checks allow COPY between physical and virtual registers,
// when the virtual register has a scalable size and the physical register
- // has a fixed size. These checks allow COPY between *potentialy* mismatched
- // sizes. However, once RegisterBankSelection occurs, MachineVerifier should
- // be able to resolve a fixed size for the scalable vector, and at that
- // point this function will know for sure whether the sizes are mismatched
- // and correctly report a size mismatch.
+ // has a fixed size. These checks allow COPY between *potentially*
+ // mismatched sizes. However, once RegisterBankSelection occurs,
+ // MachineVerifier should be able to resolve a fixed size for the scalable
+ // vector, and at that point this function will know for sure whether the
+ // sizes are mismatched and correctly report a size mismatch.
if (SrcReg.isPhysical() && DstReg.isVirtual() && DstSize.isScalable() &&
!SrcSize.isScalable())
break;
@@ -3213,13 +3213,13 @@ struct VRegFilter {
private:
static constexpr unsigned SparseUniverseMax = 10 * 1024 * 8;
- // VRegs indexed within SparseUniverseMax are tracked by Sparse, those beyound
- // are tracked by Dense. The only purpose of the threashold and the Dense set
+ // VRegs indexed within SparseUniverseMax are tracked by Sparse, those beyond
+ // are tracked by Dense. The only purpose of the threshold and the Dense set
// is to have a reasonably growing memory usage in pathological cases (large
// number of very sparse VRegFilter instances live at the same time). In
// practice even in the worst-by-execution time cases having all elements
// tracked by Sparse (very large SparseUniverseMax scenario) tends to be more
- // space efficient than if tracked by Dense. The threashold is set to keep the
+ // space efficient than if tracked by Dense. The threshold is set to keep the
// worst-case memory usage within 2x of figures determined empirically for
// "all Dense" scenario in such worst-by-execution-time cases.
BitVector Sparse;
@@ -3459,7 +3459,7 @@ void MachineVerifier::visitMachineFunctionAfter() {
// Check live-in list of each MBB. If a register is live into MBB, check
// that the register is in regsLiveOut of each predecessor block. Since
- // this must come from a definition in the predecesssor or its live-in
+ // this must come from a definition in the predecessor or its live-in
// list, this will catch a live-through case where the predecessor does not
// have the register in its live-in list. This currently only checks
// registers that have no aliases, are not allocatable and are not
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c815686..204e1f0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -11849,9 +11849,7 @@ static bool isLegalToCombineMinNumMaxNum(SelectionDAG &DAG, SDValue LHS,
if (!VT.isFloatingPoint())
return false;
- const TargetOptions &Options = DAG.getTarget().Options;
-
- return (Flags.hasNoSignedZeros() || Options.NoSignedZerosFPMath) &&
+ return Flags.hasNoSignedZeros() &&
TLI.isProfitableToCombineMinNumMaxNum(VT) &&
(Flags.hasNoNaNs() ||
(DAG.isKnownNeverNaN(RHS) && DAG.isKnownNeverNaN(LHS)));
@@ -17351,7 +17349,7 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {
// Always prefer FMAD to FMA for precision.
unsigned PreferredFusedOpcode = HasFMAD ? ISD::FMAD : ISD::FMA;
bool Aggressive = TLI.enableAggressiveFMAFusion(VT);
- bool NoSignedZero = Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros();
+ bool NoSignedZero = Flags.hasNoSignedZeros();
// Is the node an FMUL and contractable either due to global flags or
// SDNodeFlags.
@@ -17983,8 +17981,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
// (fsub A, 0) -> A
if (N1CFP && N1CFP->isZero()) {
- if (!N1CFP->isNegative() || Options.NoSignedZerosFPMath ||
- Flags.hasNoSignedZeros()) {
+ if (!N1CFP->isNegative() || Flags.hasNoSignedZeros()) {
return N0;
}
}
@@ -17997,8 +17994,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
// (fsub -0.0, N1) -> -N1
if (N0CFP && N0CFP->isZero()) {
- if (N0CFP->isNegative() ||
- (Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros())) {
+ if (N0CFP->isNegative() || Flags.hasNoSignedZeros()) {
// We cannot replace an FSUB(+-0.0,X) with FNEG(X) when denormals are
// flushed to zero, unless all users treat denorms as zero (DAZ).
// FIXME: This transform will change the sign of a NaN and the behavior
@@ -18014,8 +18010,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
}
}
- if ((Options.NoSignedZerosFPMath ||
- (Flags.hasAllowReassociation() && Flags.hasNoSignedZeros())) &&
+ if (Flags.hasAllowReassociation() && Flags.hasNoSignedZeros() &&
N1.getOpcode() == ISD::FADD) {
// X - (X + Y) -> -Y
if (N0 == N1->getOperand(0))
@@ -18330,11 +18325,9 @@ template <class MatchContextClass> SDValue DAGCombiner::visitFMA(SDNode *N) {
return matcher.getNode(ISD::FMA, DL, VT, NegN0, NegN1, N2);
}
- // FIXME: use fast math flags instead of Options.UnsafeFPMath
- // TODO: Finally migrate away from global TargetOptions.
if ((Options.NoNaNsFPMath && Options.NoInfsFPMath) ||
(N->getFlags().hasNoNaNs() && N->getFlags().hasNoInfs())) {
- if (Options.NoSignedZerosFPMath || N->getFlags().hasNoSignedZeros() ||
+ if (N->getFlags().hasNoSignedZeros() ||
(N2CFP && !N2CFP->isExactlyValue(-0.0))) {
if (N0CFP && N0CFP->isZero())
return N2;
@@ -18639,8 +18632,7 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
}
// Fold X/Sqrt(X) -> Sqrt(X)
- if ((Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros()) &&
- Flags.hasAllowReassociation())
+ if (Flags.hasNoSignedZeros() && Flags.hasAllowReassociation())
if (N1.getOpcode() == ISD::FSQRT && N0 == N1.getOperand(0))
return N1;
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index dba5a8c..cc503d3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -7492,7 +7492,6 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
// Pre-increment recursion depth for use in recursive calls.
++Depth;
const SDNodeFlags Flags = Op->getFlags();
- const TargetOptions &Options = DAG.getTarget().Options;
EVT VT = Op.getValueType();
unsigned Opcode = Op.getOpcode();
@@ -7572,7 +7571,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
return DAG.getBuildVector(VT, DL, Ops);
}
case ISD::FADD: {
- if (!Options.NoSignedZerosFPMath && !Flags.hasNoSignedZeros())
+ if (!Flags.hasNoSignedZeros())
break;
// After operation legalization, it might not be legal to create new FSUBs.
@@ -7617,7 +7616,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
}
case ISD::FSUB: {
// We can't turn -(A-B) into B-A when we honor signed zeros.
- if (!Options.NoSignedZerosFPMath && !Flags.hasNoSignedZeros())
+ if (!Flags.hasNoSignedZeros())
break;
SDValue X = Op.getOperand(0), Y = Op.getOperand(1);
@@ -7678,7 +7677,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
}
case ISD::FMA:
case ISD::FMAD: {
- if (!Options.NoSignedZerosFPMath && !Flags.hasNoSignedZeros())
+ if (!Flags.hasNoSignedZeros())
break;
SDValue X = Op.getOperand(0), Y = Op.getOperand(1), Z = Op.getOperand(2);
@@ -8797,7 +8796,6 @@ SDValue TargetLowering::expandFMINIMUMNUM_FMAXIMUMNUM(SDNode *Node,
EVT VT = Node->getValueType(0);
EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
bool IsMax = Opc == ISD::FMAXIMUMNUM;
- const TargetOptions &Options = DAG.getTarget().Options;
SDNodeFlags Flags = Node->getFlags();
unsigned NewOp =
@@ -8858,8 +8856,8 @@ SDValue TargetLowering::expandFMINIMUMNUM_FMAXIMUMNUM(SDNode *Node,
// TODO: We need quiet sNaN if strictfp.
// Fixup signed zero behavior.
- if (Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros() ||
- DAG.isKnownNeverZeroFloat(LHS) || DAG.isKnownNeverZeroFloat(RHS)) {
+ if (Flags.hasNoSignedZeros() || DAG.isKnownNeverZeroFloat(LHS) ||
+ DAG.isKnownNeverZeroFloat(RHS)) {
return MinMax;
}
SDValue TestZero =