summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/CodeGen')
-rw-r--r--contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h8
-rw-r--r--contrib/llvm/lib/CodeGen/AllocationOrder.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AntiDepBreaker.h4
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp21
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp7
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp38
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp10
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h4
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h4
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp46
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h70
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp113
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h35
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp50
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h108
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h6
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp117
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h15
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h4
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h2
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp36
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h9
-rw-r--r--contrib/llvm/lib/CodeGen/AtomicExpandPass.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/BranchFolding.cpp81
-rw-r--r--contrib/llvm/lib/CodeGen/BranchFolding.h4
-rw-r--r--contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/CoreCLRGC.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.h4
-rw-r--r--contrib/llvm/lib/CodeGen/DFAPacketizer.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/EdgeBundles.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/ExecutionDepsFix.cpp4
-rw-r--r--contrib/llvm/lib/CodeGen/FaultMaps.cpp36
-rw-r--r--contrib/llvm/lib/CodeGen/GCMetadata.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/GCRootLowering.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/IfConversion.cpp293
-rw-r--r--contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp9
-rw-r--r--contrib/llvm/lib/CodeGen/InlineSpiller.cpp4
-rw-r--r--contrib/llvm/lib/CodeGen/InterferenceCache.h2
-rw-r--r--contrib/llvm/lib/CodeGen/InterleavedAccessPass.cpp286
-rw-r--r--contrib/llvm/lib/CodeGen/LiveDebugVariables.h2
-rw-r--r--contrib/llvm/lib/CodeGen/LivePhysRegs.cpp41
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp199
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MILexer.h96
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp423
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIParser.h41
-rw-r--r--contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp99
-rw-r--r--contrib/llvm/lib/CodeGen/MIRPrinter.cpp163
-rw-r--r--contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp48
-rw-r--r--contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/MachineCombiner.cpp51
-rw-r--r--contrib/llvm/lib/CodeGen/MachineCopyPropagation.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/MachineFunction.cpp7
-rw-r--r--contrib/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/MachineInstr.cpp90
-rw-r--r--contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp129
-rw-r--r--contrib/llvm/lib/CodeGen/MachineSSAUpdater.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/MachineScheduler.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/MachineTraceMetrics.cpp22
-rw-r--r--contrib/llvm/lib/CodeGen/MachineVerifier.cpp4
-rw-r--r--contrib/llvm/lib/CodeGen/OptimizePHIs.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/PHIElimination.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/PeepholeOptimizer.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/PostRASchedulerList.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/RegAllocFast.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/RegisterCoalescer.cpp3
-rw-r--r--contrib/llvm/lib/CodeGen/RegisterCoalescer.h2
-rw-r--r--contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp87
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp23
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h4
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp27
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp3
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h2
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp3
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp55
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h3
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp51
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp40
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp21
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp23
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp6
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp45
-rw-r--r--contrib/llvm/lib/CodeGen/ShadowStackGCLowering.cpp4
-rw-r--r--contrib/llvm/lib/CodeGen/Spiller.h2
-rw-r--r--contrib/llvm/lib/CodeGen/SplitKit.h6
-rw-r--r--contrib/llvm/lib/CodeGen/StatepointExampleGC.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/TailDuplication.cpp9
-rw-r--r--contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp15
-rw-r--r--contrib/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp53
-rw-r--r--contrib/llvm/lib/CodeGen/TargetOptionsImpl.cpp7
-rw-r--r--contrib/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp20
-rw-r--r--contrib/llvm/lib/CodeGen/UnreachableBlockElim.cpp2
-rw-r--r--contrib/llvm/lib/CodeGen/WinEHPrepare.cpp92
111 files changed, 2589 insertions, 968 deletions
diff --git a/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h b/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
index 63d2085..eba7383 100644
--- a/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
+++ b/contrib/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
@@ -33,7 +33,7 @@ namespace llvm {
class RegisterClassInfo;
/// Contains all the state necessary for anti-dep breaking.
- class AggressiveAntiDepState {
+class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState {
public:
/// Information about a register reference within a liverange
typedef struct {
@@ -108,8 +108,8 @@ class RegisterClassInfo;
bool IsLive(unsigned Reg);
};
-
- class AggressiveAntiDepBreaker : public AntiDepBreaker {
+ class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepBreaker
+ : public AntiDepBreaker {
MachineFunction& MF;
MachineRegisterInfo &MRI;
const TargetInstrInfo *TII;
@@ -174,6 +174,6 @@ class RegisterClassInfo;
RenameOrderType& RenameOrder,
std::map<unsigned, unsigned> &RenameMap);
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AllocationOrder.h b/contrib/llvm/lib/CodeGen/AllocationOrder.h
index 1e4eaa7..02b2d92 100644
--- a/contrib/llvm/lib/CodeGen/AllocationOrder.h
+++ b/contrib/llvm/lib/CodeGen/AllocationOrder.h
@@ -25,7 +25,7 @@ namespace llvm {
class RegisterClassInfo;
class VirtRegMap;
-class AllocationOrder {
+class LLVM_LIBRARY_VISIBILITY AllocationOrder {
SmallVector<MCPhysReg, 16> Hints;
ArrayRef<MCPhysReg> Order;
int Pos;
diff --git a/contrib/llvm/lib/CodeGen/AntiDepBreaker.h b/contrib/llvm/lib/CodeGen/AntiDepBreaker.h
index 7985241..9f05200 100644
--- a/contrib/llvm/lib/CodeGen/AntiDepBreaker.h
+++ b/contrib/llvm/lib/CodeGen/AntiDepBreaker.h
@@ -27,7 +27,7 @@ namespace llvm {
/// This class works in conjunction with the post-RA scheduler to rename
/// registers to break register anti-dependencies (WAR hazards).
-class AntiDepBreaker {
+class LLVM_LIBRARY_VISIBILITY AntiDepBreaker {
public:
typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
DbgValueVector;
@@ -62,6 +62,6 @@ public:
}
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h
index e0ce3f9..211fc98 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h
@@ -48,5 +48,5 @@ public:
void resetUsedFlag() { HasBeenUsed = false; }
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 95da588..8a7e9f9 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -179,7 +179,7 @@ bool AsmPrinter::doInitialization(Module &M) {
OutStreamer->InitSections(false);
- Mang = new Mangler(TM.getDataLayout());
+ Mang = new Mangler();
// Emit the version-min deplyment target directive if needed.
//
@@ -2086,8 +2086,12 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
MCValue MV;
if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute())
return;
+ const MCSymbolRefExpr *SymA = MV.getSymA();
+ if (!SymA)
+ return;
- const MCSymbol *GOTEquivSym = &MV.getSymA()->getSymbol();
+ // Check that GOT equivalent symbol is cached.
+ const MCSymbol *GOTEquivSym = &SymA->getSymbol();
if (!AP.GlobalGOTEquivs.count(GOTEquivSym))
return;
@@ -2095,8 +2099,11 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
if (!BaseGV)
return;
+ // Check for a valid base symbol
const MCSymbol *BaseSym = AP.getSymbol(BaseGV);
- if (BaseSym != &MV.getSymB()->getSymbol())
+ const MCSymbolRefExpr *SymB = MV.getSymB();
+
+ if (!SymB || BaseSym != &SymB->getSymbol())
return;
// Make sure to match:
@@ -2292,11 +2299,10 @@ MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,
TM);
}
-/// GetExternalSymbolSymbol - Return the MCSymbol for the specified
-/// ExternalSymbol.
+/// Return the MCSymbol for the specified ExternalSymbol.
MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const {
SmallString<60> NameStr;
- Mang->getNameWithPrefix(NameStr, Sym);
+ Mangler::getNameWithPrefix(NameStr, Sym, *TM.getDataLayout());
return OutContext.getOrCreateSymbol(NameStr);
}
@@ -2384,8 +2390,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
if (isVerbose())
OutStreamer->AddComment("Block address taken");
- std::vector<MCSymbol*> Symbols = MMI->getAddrLabelSymbolToEmit(BB);
- for (auto *Sym : Symbols)
+ for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB))
OutStreamer->EmitLabel(Sym);
}
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 8ee613b..ad180b6 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -261,8 +261,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
// Emit the DIE attribute values.
for (const auto &V : Die.values()) {
dwarf::Attribute Attr = V.getAttribute();
- dwarf::Form Form = V.getForm();
- assert(Form && "Too many attributes for DIE (check abbreviation)");
+ assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
if (isVerbose()) {
OutStreamer->AddComment(dwarf::AttributeString(Attr));
@@ -272,13 +271,13 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
}
// Emit an attribute using the defined form.
- V.EmitValue(this, Form);
+ V.EmitValue(this);
}
// Emit the DIE children if any.
if (Die.hasChildren()) {
for (auto &Child : Die.children())
- emitDwarfDIE(*Child);
+ emitDwarfDIE(Child);
OutStreamer->AddComment("End Of Children Mark");
EmitInt8(0);
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h b/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
index 7a712a0..0cc829f 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
@@ -103,6 +103,6 @@ public:
}
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index 4847de4..46dbc76 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -165,25 +165,23 @@ void DIE::print(raw_ostream &O, unsigned IndentCount) const {
}
IndentCount += 2;
- for (unsigned i = 0, N = Values.size(); i < N; ++i) {
+ unsigned I = 0;
+ for (const auto &V : Values) {
O << Indent;
if (!isBlock)
- O << dwarf::AttributeString(Values[i].getAttribute());
+ O << dwarf::AttributeString(V.getAttribute());
else
- O << "Blk[" << i << "]";
+ O << "Blk[" << I++ << "]";
- O << " "
- << dwarf::FormEncodingString(Values[i].getForm())
- << " ";
- Values[i].print(O);
+ O << " " << dwarf::FormEncodingString(V.getForm()) << " ";
+ V.print(O);
O << "\n";
}
IndentCount -= 2;
- for (unsigned j = 0, M = Children.size(); j < M; ++j) {
- Children[j]->print(O, IndentCount+4);
- }
+ for (const auto &Child : children())
+ Child.print(O, IndentCount + 4);
if (!isBlock) O << "\n";
}
@@ -193,7 +191,7 @@ void DIE::dump() {
}
#endif
-void DIEValue::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+void DIEValue::EmitValue(const AsmPrinter *AP) const {
switch (Ty) {
case isNone:
llvm_unreachable("Expected valid DIEValue");
@@ -205,7 +203,7 @@ void DIEValue::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
}
}
-unsigned DIEValue::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
+unsigned DIEValue::SizeOf(const AsmPrinter *AP) const {
switch (Ty) {
case isNone:
llvm_unreachable("Expected valid DIEValue");
@@ -507,8 +505,8 @@ void DIETypeSignature::print(raw_ostream &O) const {
///
unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const {
if (!Size) {
- for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Size += Values[i].SizeOf(AP, Values[i].getForm());
+ for (const auto &V : Values)
+ Size += V.SizeOf(AP);
}
return Size;
@@ -527,8 +525,8 @@ void DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
Asm->EmitULEB128(Size); break;
}
- for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Values[i].EmitValue(Asm, Values[i].getForm());
+ for (const auto &V : Values)
+ V.EmitValue(Asm);
}
/// SizeOf - Determine size of location data in bytes.
@@ -560,8 +558,8 @@ void DIELoc::print(raw_ostream &O) const {
///
unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const {
if (!Size) {
- for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Size += Values[i].SizeOf(AP, Values[i].getForm());
+ for (const auto &V : Values)
+ Size += V.SizeOf(AP);
}
return Size;
@@ -578,8 +576,8 @@ void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
}
- for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Values[i].EmitValue(Asm, Values[i].getForm());
+ for (const auto &V : Values)
+ V.EmitValue(Asm);
}
/// SizeOf - Determine size of block data in bytes.
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
index 1445254..5e60156 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -263,7 +263,7 @@ void DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag,
// Hash all of the values in a block like set of values. This assumes that
// all of the data is going to be added as integers.
-void DIEHash::hashBlockData(const DIE::value_range &Values) {
+void DIEHash::hashBlockData(const DIE::const_value_range &Values) {
for (const auto &V : Values)
Hash.update((uint64_t)V.getDIEInteger().getValue());
}
@@ -454,15 +454,15 @@ void DIEHash::computeHash(const DIE &Die) {
for (auto &C : Die.children()) {
// 7.27 Step 7
// If C is a nested type entry or a member function entry, ...
- if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) {
- StringRef Name = getDIEStringAttr(*C, dwarf::DW_AT_name);
+ if (isType(C.getTag()) || C.getTag() == dwarf::DW_TAG_subprogram) {
+ StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name);
// ... and has a DW_AT_name attribute
if (!Name.empty()) {
- hashNestedType(*C, Name);
+ hashNestedType(C, Name);
continue;
}
}
- computeHash(*C);
+ computeHash(C);
}
// Following the last (or if there are no children), append a zero byte.
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
index 789e6dd..833ca02 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -128,7 +128,7 @@ private:
/// \brief Hashes the data in a block like DIEValue, e.g. DW_FORM_block or
/// DW_FORM_exprloc.
- void hashBlockData(const DIE::value_range &Values);
+ void hashBlockData(const DIE::const_value_range &Values);
/// \brief Hashes the contents pointed to in the .debug_loc section.
void hashLocList(const DIELocList &LocList);
@@ -157,6 +157,6 @@ private:
AsmPrinter *AP;
DenseMap<const DIE *, unsigned> Numbering;
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
index 5d40050..546d1b4 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
@@ -55,6 +55,6 @@ public:
void calculateDbgValueHistory(const MachineFunction *MF,
const TargetRegisterInfo *TRI,
DbgValueHistoryMap &Result);
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 083228b..afffa83 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -142,7 +142,7 @@ public:
}
/// \brief Lower this entry into a DWARF expression.
- void finalize(const AsmPrinter &AP, DebugLocStream &Locs,
+ void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List,
const DIBasicType *BT);
};
@@ -175,6 +175,6 @@ inline bool operator<(const DebugLocEntry::Value &A,
B.getExpression()->getBitPieceOffset();
}
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp
new file mode 100644
index 0000000..7e8ed71
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp
@@ -0,0 +1,46 @@
+//===- DebugLocStream.cpp - DWARF debug_loc stream --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugLocStream.h"
+#include "DwarfDebug.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+
+using namespace llvm;
+
+bool DebugLocStream::finalizeList(AsmPrinter &Asm) {
+ if (Lists.back().EntryOffset == Entries.size()) {
+ // Empty list. Delete it.
+ Lists.pop_back();
+ return false;
+ }
+
+ // Real list. Generate a label for it.
+ Lists.back().Label = Asm.createTempSymbol("debug_loc");
+ return true;
+}
+
+void DebugLocStream::finalizeEntry() {
+ if (Entries.back().ByteOffset != DWARFBytes.size())
+ return;
+
+ // The last entry was empty. Delete it.
+ Comments.erase(Comments.begin() + Entries.back().CommentOffset,
+ Comments.end());
+ Entries.pop_back();
+
+ assert(Lists.back().EntryOffset <= Entries.size() &&
+ "Popped off more entries than are in the list");
+}
+
+DebugLocStream::ListBuilder::~ListBuilder() {
+ if (!Locs.finalizeList(Asm))
+ return;
+ V.initializeDbgValue(&MI);
+ V.setDebugLocListIndex(ListIndex);
+}
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
index 1ae385d..3656e9d 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
@@ -15,7 +15,11 @@
#include "ByteStreamer.h"
namespace llvm {
+
+class AsmPrinter;
+class DbgVariable;
class DwarfCompileUnit;
+class MachineInstr;
class MCSymbol;
/// \brief Byte stream of .debug_loc entries.
@@ -29,10 +33,10 @@ class DebugLocStream {
public:
struct List {
DwarfCompileUnit *CU;
- MCSymbol *Label;
+ MCSymbol *Label = nullptr;
size_t EntryOffset;
- List(DwarfCompileUnit *CU, MCSymbol *Label, size_t EntryOffset)
- : CU(CU), Label(Label), EntryOffset(EntryOffset) {}
+ List(DwarfCompileUnit *CU, size_t EntryOffset)
+ : CU(CU), EntryOffset(EntryOffset) {}
};
struct Entry {
const MCSymbol *BeginSym;
@@ -61,18 +65,30 @@ public:
const List &getList(size_t LI) const { return Lists[LI]; }
ArrayRef<List> getLists() const { return Lists; }
+ class ListBuilder;
+ class EntryBuilder;
+
+private:
/// \brief Start a new .debug_loc entry list.
///
/// Start a new .debug_loc entry list. Return the new list's index so it can
/// be retrieved later via \a getList().
///
/// Until the next call, \a startEntry() will add entries to this list.
- size_t startList(DwarfCompileUnit *CU, MCSymbol *Label) {
+ size_t startList(DwarfCompileUnit *CU) {
size_t LI = Lists.size();
- Lists.emplace_back(CU, Label, Entries.size());
+ Lists.emplace_back(CU, Entries.size());
return LI;
}
+ /// Finalize a .debug_loc entry list.
+ ///
+ /// If there are no entries in this list, delete it outright. Otherwise,
+ /// create a label with \a Asm.
+ ///
+ /// \return false iff the list is deleted.
+ bool finalizeList(AsmPrinter &Asm);
+
/// \brief Start a new .debug_loc entry.
///
/// Until the next call, bytes added to the stream will be added to this
@@ -81,6 +97,10 @@ public:
Entries.emplace_back(BeginSym, EndSym, DWARFBytes.size(), Comments.size());
}
+ /// Finalize a .debug_loc entry, deleting if it's empty.
+ void finalizeEntry();
+
+public:
BufferByteStreamer getStreamer() {
return BufferByteStreamer(DWARFBytes, Comments, GenerateComments);
}
@@ -129,5 +149,45 @@ private:
return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset;
}
};
+
+/// Builder for DebugLocStream lists.
+class DebugLocStream::ListBuilder {
+ DebugLocStream &Locs;
+ AsmPrinter &Asm;
+ DbgVariable &V;
+ const MachineInstr &MI;
+ size_t ListIndex;
+
+public:
+ ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm,
+ DbgVariable &V, const MachineInstr &MI)
+ : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)) {}
+
+ /// Finalize the list.
+ ///
+ /// If the list is empty, delete it. Otherwise, finalize it by creating a
+ /// temp symbol in \a Asm and setting up the \a DbgVariable.
+ ~ListBuilder();
+
+ DebugLocStream &getLocs() { return Locs; }
+};
+
+/// Builder for DebugLocStream entries.
+class DebugLocStream::EntryBuilder {
+ DebugLocStream &Locs;
+
+public:
+ EntryBuilder(ListBuilder &List, const MCSymbol *Begin, const MCSymbol *End)
+ : Locs(List.getLocs()) {
+ Locs.startEntry(Begin, End);
+ }
+
+ /// Finalize the entry, deleting it if it's empty.
+ ~EntryBuilder() { Locs.finalizeEntry(); }
+
+ BufferByteStreamer getStreamer() { return Locs.getStreamer(); }
+};
+
} // namespace llvm
+
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
index cc677c2..4d81441 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
@@ -252,5 +252,5 @@ public:
void dump() { print(dbgs()); }
#endif
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 45c56fb..fc54a29 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -42,7 +42,8 @@ void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
DD->addArangeLabel(SymbolCU(this, Label));
unsigned idx = DD->getAddressPool().getIndex(Label);
- Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, DIEInteger(idx));
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_GNU_addr_index,
+ DIEInteger(idx));
}
void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
@@ -52,9 +53,11 @@ void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
DD->addArangeLabel(SymbolCU(this, Label));
if (Label)
- Die.addValue(Attribute, dwarf::DW_FORM_addr, DIELabel(Label));
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
+ DIELabel(Label));
else
- Die.addValue(Attribute, dwarf::DW_FORM_addr, DIEInteger(0));
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
+ DIEInteger(0));
}
unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName,
@@ -225,16 +228,15 @@ void DwarfCompileUnit::addRange(RangeSpan Range) {
CURanges.back().setEnd(Range.getEnd());
}
-void DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
- const MCSymbol *Label,
- const MCSymbol *Sec) {
+DIE::value_iterator
+DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
+ const MCSymbol *Label, const MCSymbol *Sec) {
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- addLabel(Die, Attribute,
- DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
- : dwarf::DW_FORM_data4,
- Label);
- else
- addSectionDelta(Die, Attribute, Label, Sec);
+ return addLabel(Die, Attribute,
+ DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
+ : dwarf::DW_FORM_data4,
+ Label);
+ return addSectionDelta(Die, Attribute, Label, Sec);
}
void DwarfCompileUnit::initStmtList() {
@@ -242,20 +244,19 @@ void DwarfCompileUnit::initStmtList() {
MCSymbol *LineTableStartSym =
Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID());
- stmtListIndex = std::distance(UnitDie.values_begin(), UnitDie.values_end());
-
// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section. For split dwarf this is
// left in the skeleton CU and so not included.
// The line table entries are not always emitted in assembly, so it
// is not okay to use line_table_start here.
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
- addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym,
- TLOF.getDwarfLineSection()->getBeginSymbol());
+ StmtListValue =
+ addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym,
+ TLOF.getDwarfLineSection()->getBeginSymbol());
}
void DwarfCompileUnit::applyStmtList(DIE &D) {
- D.addValue(UnitDie.values_begin()[stmtListIndex]);
+ D.addValue(DIEValueAllocator, *StmtListValue);
}
void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
@@ -300,7 +301,7 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
// Construct a DIE for this scope.
void DwarfCompileUnit::constructScopeDIE(
- LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
+ LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) {
if (!Scope || !Scope->getScopeNode())
return;
@@ -311,12 +312,12 @@ void DwarfCompileUnit::constructScopeDIE(
"constructSubprogramScopeDIE for non-inlined "
"subprograms");
- SmallVector<std::unique_ptr<DIE>, 8> Children;
+ SmallVector<DIE *, 8> Children;
// We try to create the scope DIE first, then the children DIEs. This will
// avoid creating un-used children then removing them later when we find out
// the scope DIE is null.
- std::unique_ptr<DIE> ScopeDIE;
+ DIE *ScopeDIE;
if (Scope->getParent() && isa<DISubprogram>(DS)) {
ScopeDIE = constructInlinedScopeDIE(Scope);
if (!ScopeDIE)
@@ -361,11 +362,13 @@ void DwarfCompileUnit::constructScopeDIE(
FinalChildren.push_back(std::move(ScopeDIE));
}
-void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
- const MCSymbol *Hi, const MCSymbol *Lo) {
- Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
- : dwarf::DW_FORM_data4,
- new (DIEValueAllocator) DIEDelta(Hi, Lo));
+DIE::value_iterator
+DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
+ const MCSymbol *Hi, const MCSymbol *Lo) {
+ return Die.addValue(DIEValueAllocator, Attribute,
+ DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
+ : dwarf::DW_FORM_data4,
+ new (DIEValueAllocator) DIEDelta(Hi, Lo));
}
void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
@@ -413,8 +416,7 @@ void DwarfCompileUnit::attachRangesOrLowHighPC(
// This scope represents inlined body of a function. Construct DIE to
// represent this concrete inlined copy of the function.
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
+DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
assert(Scope->getScopeNode());
auto *DS = Scope->getScopeNode();
auto *InlinedSP = getDISubprogram(DS);
@@ -423,7 +425,7 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP];
assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
- auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine);
+ auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
@@ -443,12 +445,11 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
// Construct new DW_TAG_lexical_block for this scope and attach
// DW_AT_low_pc/DW_AT_high_pc labels.
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
+DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
if (DD->isLexicalScopeDIENull(Scope))
return nullptr;
- auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block);
+ auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope())
return ScopeDIE;
@@ -458,18 +459,16 @@ DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
}
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
-std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
- bool Abstract) {
+DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
auto D = constructVariableDIEImpl(DV, Abstract);
DV.setDIE(*D);
return D;
}
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
- bool Abstract) {
+DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
+ bool Abstract) {
// Define variable debug information entry.
- auto VariableDie = make_unique<DIE>(DV.getTag());
+ auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
if (Abstract) {
applyVariableAttributes(DV, *VariableDie);
@@ -508,7 +507,7 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
}
// .. else use frame index.
- if (DV.getFrameIndex().back() == ~0)
+ if (DV.getFrameIndex().empty())
return VariableDie;
auto Expr = DV.getExpression().begin();
@@ -529,17 +528,18 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
return VariableDie;
}
-std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(
- DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) {
+DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
+ const LexicalScope &Scope,
+ DIE *&ObjectPointer) {
auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
if (DV.isObjectPointer())
- ObjectPointer = Var.get();
+ ObjectPointer = Var;
return Var;
}
-DIE *DwarfCompileUnit::createScopeChildrenDIE(
- LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &Children,
- unsigned *ChildScopeCount) {
+DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
+ SmallVectorImpl<DIE *> &Children,
+ unsigned *ChildScopeCount) {
DIE *ObjectPointer = nullptr;
for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope))
@@ -580,13 +580,14 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
// variadic function.
if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
!includeMinimalInlineScopes())
- ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
+ ScopeDIE.addChild(
+ DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
}
DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
DIE &ScopeDIE) {
// We create children when the scope DIE is not null.
- SmallVector<std::unique_ptr<DIE>, 8> Children;
+ SmallVector<DIE *, 8> Children;
DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children);
// Add children
@@ -629,14 +630,16 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
}
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity *Module) {
- std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module->getTag());
- insertDIE(Module, IMDie.get());
+DIE *DwarfCompileUnit::constructImportedEntityDIE(
+ const DIImportedEntity *Module) {
+ DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
+ insertDIE(Module, IMDie);
DIE *EntityDie;
auto *Entity = resolve(Module->getEntity());
if (auto *NS = dyn_cast<DINamespace>(Entity))
EntityDie = getOrCreateNameSpace(NS);
+ else if (auto *M = dyn_cast<DIModule>(Entity))
+ EntityDie = getOrCreateModule(M);
else if (auto *SP = dyn_cast<DISubprogram>(Entity))
EntityDie = getOrCreateSubprogramDIE(SP);
else if (auto *T = dyn_cast<DIType>(Entity))
@@ -686,7 +689,7 @@ void DwarfCompileUnit::collectDeadVariables(const DISubprogram *SP) {
SPDIE = getDIE(SP);
assert(SPDIE);
for (const DILocalVariable *DV : Variables) {
- DbgVariable NewVar(DV, /* IA */ nullptr, /* Expr */ nullptr, DD);
+ DbgVariable NewVar(DV, /* IA */ nullptr, DD);
auto VariableDie = constructVariableDIE(NewVar);
applyVariableAttributes(NewVar, *VariableDie);
SPDIE->addChild(std::move(VariableDie));
@@ -725,7 +728,7 @@ void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
/// DbgVariable based on provided MachineLocation.
void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
MachineLocation Location) {
- if (DV.variableHasComplexAddress())
+ if (DV.hasComplexAddress())
addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
else if (DV.isBlockByrefVariable())
addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
@@ -781,7 +784,7 @@ void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
unsigned Index) {
dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
: dwarf::DW_FORM_data4;
- Die.addValue(Attribute, Form, DIELocList(Index));
+ Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index));
}
void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
@@ -798,7 +801,7 @@ void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var,
/// Add a Dwarf expression attribute data and value.
void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
const MCExpr *Expr) {
- Die.addValue((dwarf::Attribute)0, Form, DIEExpr(Expr));
+ Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr));
}
void DwarfCompileUnit::applySubprogramAttributesToDefinition(
@@ -817,4 +820,4 @@ bool DwarfCompileUnit::includeMinimalInlineScopes() const {
return getCUNode()->getEmissionKind() == DIBuilder::LineTablesOnly ||
(DD->useSplitDwarf() && !Skeleton);
}
-} // namespace llvm
+} // end llvm namespace
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 48c302b..509c943 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -31,7 +31,7 @@ class LexicalScope;
class DwarfCompileUnit : public DwarfUnit {
/// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding
/// the need to search for it in applyStmtList.
- unsigned stmtListIndex;
+ DIE::value_iterator StmtListValue;
/// Skeleton unit associated with this unit.
DwarfCompileUnit *Skeleton;
@@ -58,8 +58,7 @@ class DwarfCompileUnit : public DwarfUnit {
/// \brief Construct a DIE for the given DbgVariable without initializing the
/// DbgVariable's DIE reference.
- std::unique_ptr<DIE> constructVariableDIEImpl(const DbgVariable &DV,
- bool Abstract);
+ DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract);
bool isDwoUnit() const override;
@@ -92,8 +91,8 @@ public:
const MCSymbol *Label);
/// addSectionDelta - Add a label delta attribute data and value.
- void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
- const MCSymbol *Lo);
+ DIE::value_iterator addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
+ const MCSymbol *Hi, const MCSymbol *Lo);
DwarfCompileUnit &getCU() override { return *this; }
@@ -106,8 +105,9 @@ public:
/// addSectionLabel - Add a Dwarf section label attribute data and value.
///
- void addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
- const MCSymbol *Label, const MCSymbol *Sec);
+ DIE::value_iterator addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
+ const MCSymbol *Label,
+ const MCSymbol *Sec);
/// \brief Find DIE for the given subprogram and attach appropriate
/// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global
@@ -116,7 +116,7 @@ public:
DIE &updateSubprogramScopeDIE(const DISubprogram *SP);
void constructScopeDIE(LexicalScope *Scope,
- SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren);
+ SmallVectorImpl<DIE *> &FinalChildren);
/// \brief A helper function to construct a RangeSpanList for a given
/// lexical scope.
@@ -128,23 +128,21 @@ public:
const SmallVectorImpl<InsnRange> &Ranges);
/// \brief This scope represents inlined body of a function. Construct
/// DIE to represent this concrete inlined copy of the function.
- std::unique_ptr<DIE> constructInlinedScopeDIE(LexicalScope *Scope);
+ DIE *constructInlinedScopeDIE(LexicalScope *Scope);
/// \brief Construct new DW_TAG_lexical_block for this scope and
/// attach DW_AT_low_pc/DW_AT_high_pc labels.
- std::unique_ptr<DIE> constructLexicalScopeDIE(LexicalScope *Scope);
+ DIE *constructLexicalScopeDIE(LexicalScope *Scope);
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
- std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV,
- bool Abstract = false);
+ DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);
- std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV,
- const LexicalScope &Scope,
- DIE *&ObjectPointer);
+ DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
+ DIE *&ObjectPointer);
/// A helper function to create children of a Scope DIE.
DIE *createScopeChildrenDIE(LexicalScope *Scope,
- SmallVectorImpl<std::unique_ptr<DIE>> &Children,
+ SmallVectorImpl<DIE *> &Children,
unsigned *ChildScopeCount = nullptr);
/// \brief Construct a DIE for this subprogram scope.
@@ -155,8 +153,7 @@ public:
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
/// \brief Construct import_module DIE.
- std::unique_ptr<DIE>
- constructImportedEntityDIE(const DIImportedEntity *Module);
+ DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
void finishSubprogramDefinition(const DISubprogram *SP);
@@ -231,6 +228,6 @@ public:
const MCSymbol *getBaseAddress() const { return BaseAddress; }
};
-} // namespace llvm
+} // end llvm namespace
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index fb33169..7d03a39 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -678,8 +678,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV) {
void DwarfDebug::createAbstractVariable(const DILocalVariable *Var,
LexicalScope *Scope) {
- auto AbsDbgVariable =
- make_unique<DbgVariable>(Var, /* IA */ nullptr, /* Expr */ nullptr, this);
+ auto AbsDbgVariable = make_unique<DbgVariable>(Var, /* IA */ nullptr, this);
InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get());
AbstractVariables[Var] = std::move(AbsDbgVariable);
}
@@ -722,10 +721,9 @@ void DwarfDebug::collectVariableInfoFromMMITable(
if (!Scope)
continue;
- const DIExpression *Expr = cast_or_null<DIExpression>(VI.Expr);
ensureAbstractVariableIsCreatedIfScoped(Var, Scope->getScopeNode());
- auto RegVar =
- make_unique<DbgVariable>(Var.first, Var.second, Expr, this, VI.Slot);
+ auto RegVar = make_unique<DbgVariable>(Var.first, Var.second, this);
+ RegVar->initializeMMI(VI.Expr, VI.Slot);
if (InfoHolder.addScopeVariable(Scope, RegVar.get()))
ConcreteVariables.push_back(std::move(RegVar));
}
@@ -870,6 +868,14 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
}
}
+DbgVariable *DwarfDebug::createConcreteVariable(LexicalScope &Scope,
+ InlinedVariable IV) {
+ ensureAbstractVariableIsCreatedIfScoped(IV, Scope.getScopeNode());
+ ConcreteVariables.push_back(
+ make_unique<DbgVariable>(IV.first, IV.second, this));
+ InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
+ return ConcreteVariables.back().get();
+}
// Find variables for each lexical scope.
void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
@@ -898,20 +904,19 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
continue;
Processed.insert(IV);
+ DbgVariable *RegVar = createConcreteVariable(*Scope, IV);
+
const MachineInstr *MInsn = Ranges.front().first;
assert(MInsn->isDebugValue() && "History must begin with debug value");
- ensureAbstractVariableIsCreatedIfScoped(IV, Scope->getScopeNode());
- ConcreteVariables.push_back(make_unique<DbgVariable>(MInsn, this));
- DbgVariable *RegVar = ConcreteVariables.back().get();
- InfoHolder.addScopeVariable(Scope, RegVar);
// Check if the first DBG_VALUE is valid for the rest of the function.
- if (Ranges.size() == 1 && Ranges.front().second == nullptr)
+ if (Ranges.size() == 1 && Ranges.front().second == nullptr) {
+ RegVar->initializeDbgValue(MInsn);
continue;
+ }
// Handle multiple DBG_VALUE instructions describing one variable.
- RegVar->setDebugLocListIndex(
- DebugLocs.startList(&TheCU, Asm->createTempSymbol("debug_loc")));
+ DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar, *MInsn);
// Build the location list for this variable.
SmallVector<DebugLocEntry, 8> Entries;
@@ -925,20 +930,14 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
// Finalize the entry by lowering it into a DWARF bytestream.
for (auto &Entry : Entries)
- Entry.finalize(*Asm, DebugLocs, BT);
+ Entry.finalize(*Asm, List, BT);
}
// Collect info for variables that were optimized out.
for (const DILocalVariable *DV : SP->getVariables()) {
- if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
- continue;
- if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) {
- ensureAbstractVariableIsCreatedIfScoped(InlinedVariable(DV, nullptr),
- Scope->getScopeNode());
- ConcreteVariables.push_back(make_unique<DbgVariable>(
- DV, /* IA */ nullptr, /* Expr */ nullptr, this));
- InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get());
- }
+ if (Processed.insert(InlinedVariable(DV, nullptr)).second)
+ if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope()))
+ createConcreteVariable(*Scope, InlinedVariable(DV, nullptr));
}
}
@@ -1505,10 +1504,11 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
// FIXME: ^
}
-void DebugLocEntry::finalize(const AsmPrinter &AP, DebugLocStream &Locs,
+void DebugLocEntry::finalize(const AsmPrinter &AP,
+ DebugLocStream::ListBuilder &List,
const DIBasicType *BT) {
- Locs.startEntry(Begin, End);
- BufferByteStreamer Streamer = Locs.getStreamer();
+ DebugLocStream::EntryBuilder Entry(List, Begin, End);
+ BufferByteStreamer Streamer = Entry.getStreamer();
const DebugLocEntry::Value &Value = Values[0];
if (Value.isBitPiece()) {
// Emit all pieces that belong to the same variable and range.
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 700f736..1c3e2ae 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -67,42 +67,61 @@ public:
};
//===----------------------------------------------------------------------===//
-/// \brief This class is used to track local variable information.
+/// This class is used to track local variable information.
///
-/// - Variables whose location changes over time have a DebugLocListIndex and
-/// the other fields are not used.
+/// Variables can be created from allocas, in which case they're generated from
+/// the MMI table. Such variables can have multiple expressions and frame
+/// indices. The \a Expr and \a FrameIndices array must match.
///
-/// - Variables that are described by multiple MMI table entries have multiple
-/// expressions and frame indices.
+/// Variables can be created from \c DBG_VALUE instructions. Those whose
+/// location changes over time use \a DebugLocListIndex, while those with a
+/// single instruction use \a MInsn and (optionally) a single entry of \a Expr.
+///
+/// Variables that have been optimized out use none of these fields.
class DbgVariable {
- const DILocalVariable *Var; /// Variable Descriptor.
- const DILocation *IA; /// Inlined at location.
- SmallVector<const DIExpression *, 1>
- Expr; /// Complex address location expression.
- DIE *TheDIE; /// Variable DIE.
- unsigned DebugLocListIndex; /// Offset in DebugLocs.
- const MachineInstr *MInsn; /// DBG_VALUE instruction of the variable.
- SmallVector<int, 1> FrameIndex; /// Frame index of the variable.
+ const DILocalVariable *Var; /// Variable Descriptor.
+ const DILocation *IA; /// Inlined at location.
+ SmallVector<const DIExpression *, 1> Expr; /// Complex address.
+ DIE *TheDIE = nullptr; /// Variable DIE.
+ unsigned DebugLocListIndex = ~0u; /// Offset in DebugLocs.
+ const MachineInstr *MInsn = nullptr; /// DBG_VALUE instruction.
+ SmallVector<int, 1> FrameIndex; /// Frame index.
DwarfDebug *DD;
public:
- /// Construct a DbgVariable from a variable.
- DbgVariable(const DILocalVariable *V, const DILocation *IA,
- const DIExpression *E, DwarfDebug *DD, int FI = ~0)
- : Var(V), IA(IA), Expr(1, E), TheDIE(nullptr), DebugLocListIndex(~0U),
- MInsn(nullptr), DD(DD) {
+ /// Construct a DbgVariable.
+ ///
+ /// Creates a variable without any DW_AT_location. Call \a initializeMMI()
+ /// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions.
+ DbgVariable(const DILocalVariable *V, const DILocation *IA, DwarfDebug *DD)
+ : Var(V), IA(IA), DD(DD) {}
+
+ /// Initialize from the MMI table.
+ void initializeMMI(const DIExpression *E, int FI) {
+ assert(Expr.empty() && "Already initialized?");
+ assert(FrameIndex.empty() && "Already initialized?");
+ assert(!MInsn && "Already initialized?");
+
+ assert((!E || E->isValid()) && "Expected valid expression");
+ assert(~FI && "Expected valid index");
+
+ Expr.push_back(E);
FrameIndex.push_back(FI);
- assert(!E || E->isValid());
}
- /// Construct a DbgVariable from a DEBUG_VALUE.
- /// AbstractVar may be NULL.
- DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD)
- : Var(DbgValue->getDebugVariable()),
- IA(DbgValue->getDebugLoc()->getInlinedAt()),
- Expr(1, DbgValue->getDebugExpression()), TheDIE(nullptr),
- DebugLocListIndex(~0U), MInsn(DbgValue), DD(DD) {
- FrameIndex.push_back(~0);
+ /// Initialize from a DBG_VALUE instruction.
+ void initializeDbgValue(const MachineInstr *DbgValue) {
+ assert(Expr.empty() && "Already initialized?");
+ assert(FrameIndex.empty() && "Already initialized?");
+ assert(!MInsn && "Already initialized?");
+
+ assert(Var == DbgValue->getDebugVariable() && "Wrong variable");
+ assert(IA == DbgValue->getDebugLoc()->getInlinedAt() && "Wrong inlined-at");
+
+ MInsn = DbgValue;
+ if (auto *E = DbgValue->getDebugExpression())
+ if (E->getNumElements())
+ Expr.push_back(E);
}
// Accessors.
@@ -123,17 +142,16 @@ public:
assert(V.Var == Var && "conflicting variable");
assert(V.IA == IA && "conflicting inlined-at location");
- if (V.getFrameIndex().back() != ~0) {
- auto E = V.getExpression();
- auto FI = V.getFrameIndex();
- Expr.append(E.begin(), E.end());
- FrameIndex.append(FI.begin(), FI.end());
- }
- assert(Expr.size() > 1 ? std::all_of(Expr.begin(), Expr.end(),
- [](const DIExpression *E) {
- return E->isBitPiece();
- })
- : (true && "conflicting locations for variable"));
+ assert(!FrameIndex.empty() && "Expected an MMI entry");
+ assert(!V.FrameIndex.empty() && "Expected an MMI entry");
+ assert(Expr.size() == FrameIndex.size() && "Mismatched expressions");
+ assert(V.Expr.size() == V.FrameIndex.size() && "Mismatched expressions");
+
+ Expr.append(V.Expr.begin(), V.Expr.end());
+ FrameIndex.append(V.FrameIndex.begin(), V.FrameIndex.end());
+ assert(std::all_of(Expr.begin(), Expr.end(), [](const DIExpression *E) {
+ return E && E->isBitPiece();
+ }) && "conflicting locations for variable");
}
// Translate tag to proper Dwarf tag.
@@ -160,11 +178,13 @@ public:
return false;
}
- bool variableHasComplexAddress() const {
- assert(Var && "Invalid complex DbgVariable!");
- assert(Expr.size() == 1 &&
- "variableHasComplexAddress() invoked on multi-FI variable");
- return Expr.back()->getNumElements() > 0;
+ bool hasComplexAddress() const {
+ assert(MInsn && "Expected DBG_VALUE, not MMI variable");
+ assert(FrameIndex.empty() && "Expected DBG_VALUE, not MMI variable");
+ assert(
+ (Expr.empty() || (Expr.size() == 1 && Expr.back()->getNumElements())) &&
+ "Invalid Expr for DBG_VALUE");
+ return !Expr.empty();
}
bool isBlockByrefVariable() const;
const DIType *getType() const;
@@ -344,6 +364,8 @@ class DwarfDebug : public AsmPrinterHandler {
void ensureAbstractVariableIsCreatedIfScoped(InlinedVariable Var,
const MDNode *Scope);
+ DbgVariable *createConcreteVariable(LexicalScope &Scope, InlinedVariable IV);
+
/// \brief Construct a DIE for this abstract scope.
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
index a4fd36f..f4667b4 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -21,7 +21,7 @@ namespace llvm {
class MachineFunction;
class ARMTargetStreamer;
-class DwarfCFIExceptionBase : public EHStreamer {
+class LLVM_LIBRARY_VISIBILITY DwarfCFIExceptionBase : public EHStreamer {
protected:
DwarfCFIExceptionBase(AsmPrinter *A);
@@ -31,7 +31,7 @@ protected:
void markFunctionEnd() override;
};
-class DwarfCFIException : public DwarfCFIExceptionBase {
+class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public DwarfCFIExceptionBase {
/// Per-function flag to indicate if .cfi_personality should be emitted.
bool shouldEmitPersonality;
@@ -61,7 +61,7 @@ public:
void endFunction(const MachineFunction *) override;
};
-class ARMException : public DwarfCFIExceptionBase {
+class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {
void emitTypeInfos(unsigned TTypeEncoding) override;
ARMTargetStreamer &getTargetStreamer();
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 154d7d9..78ec937 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -131,6 +131,6 @@ public:
void EmitUnsigned(uint64_t Value) override;
bool isFrameRegister(unsigned MachineReg) override;
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
index fdefb1d..51b27b4 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -103,7 +103,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
// Size the DIE attribute values.
for (const auto &V : Die.values())
// Size attribute value.
- Offset += V.SizeOf(Asm, V.getForm());
+ Offset += V.SizeOf(Asm);
// Size the DIE children if any.
if (Die.hasChildren()) {
@@ -111,7 +111,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
assert(Abbrev.hasChildren() && "Children flag not set");
for (auto &Child : Die.children())
- Offset = computeSizeAndOffset(*Child, Offset);
+ Offset = computeSizeAndOffset(Child, Offset);
// End of children marker.
Offset += sizeof(int8_t);
@@ -170,4 +170,4 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
Vars.push_back(Var);
return true;
}
-} // namespace llvm
+}
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
index 22759fd..8402027 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
@@ -114,5 +114,5 @@ public:
return DITypeNodeToDieMap.lookup(TypeMD);
}
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h
index c107258..93a1684 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h
@@ -45,5 +45,5 @@ public:
/// Get a reference to an entry in the string pool.
EntryRef getEntry(AsmPrinter &Asm, StringRef Str);
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index f4b15ba..3555822 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -66,8 +66,9 @@ bool DIEDwarfExpression::isFrameRegister(unsigned MachineReg) {
DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag,
const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW,
DwarfFile *DWU)
- : UniqueID(UID), CUNode(Node), UnitDie(UnitTag), DebugInfoOffset(0), Asm(A),
- DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) {
+ : UniqueID(UID), CUNode(Node),
+ UnitDie(*DIE::get(DIEValueAllocator, UnitTag)), DebugInfoOffset(0),
+ Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) {
assert(UnitTag == dwarf::DW_TAG_compile_unit ||
UnitTag == dwarf::DW_TAG_type_unit);
}
@@ -184,16 +185,18 @@ void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) {
void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) {
if (DD->getDwarfVersion() >= 4)
- Die.addValue(Attribute, dwarf::DW_FORM_flag_present, DIEInteger(1));
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag_present,
+ DIEInteger(1));
else
- Die.addValue(Attribute, dwarf::DW_FORM_flag, DIEInteger(1));
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag,
+ DIEInteger(1));
}
void DwarfUnit::addUInt(DIE &Die, dwarf::Attribute Attribute,
Optional<dwarf::Form> Form, uint64_t Integer) {
if (!Form)
Form = DIEInteger::BestForm(false, Integer);
- Die.addValue(Attribute, *Form, DIEInteger(Integer));
+ Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer));
}
void DwarfUnit::addUInt(DIE &Block, dwarf::Form Form, uint64_t Integer) {
@@ -204,7 +207,7 @@ void DwarfUnit::addSInt(DIE &Die, dwarf::Attribute Attribute,
Optional<dwarf::Form> Form, int64_t Integer) {
if (!Form)
Form = DIEInteger::BestForm(true, Integer);
- Die.addValue(Attribute, *Form, DIEInteger(Integer));
+ Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer));
}
void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form,
@@ -214,14 +217,15 @@ void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form,
void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute,
StringRef String) {
- Die.addValue(Attribute,
+ Die.addValue(DIEValueAllocator, Attribute,
isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp,
DIEString(DU->getStringPool().getEntry(*Asm, String)));
}
-void DwarfUnit::addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form,
- const MCSymbol *Label) {
- Die.addValue(Attribute, Form, DIELabel(Label));
+DIE::value_iterator DwarfUnit::addLabel(DIE &Die, dwarf::Attribute Attribute,
+ dwarf::Form Form,
+ const MCSymbol *Label) {
+ return Die.addValue(DIEValueAllocator, Attribute, Form, DIELabel(Label));
}
void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) {
@@ -254,7 +258,7 @@ void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {
void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Hi, const MCSymbol *Lo) {
- Die.addValue(Attribute, dwarf::DW_FORM_data4,
+ Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_data4,
new (DIEValueAllocator) DIEDelta(Hi, Lo));
}
@@ -269,8 +273,8 @@ void DwarfUnit::addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type) {
// and think this is a full definition.
addFlag(Die, dwarf::DW_AT_declaration);
- Die.addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,
- DIETypeSignature(Type));
+ Die.addValue(DIEValueAllocator, dwarf::DW_AT_signature,
+ dwarf::DW_FORM_ref_sig8, DIETypeSignature(Type));
}
void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,
@@ -282,7 +286,7 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,
DieCU = &getUnitDie();
if (!EntryCU)
EntryCU = &getUnitDie();
- Die.addValue(Attribute,
+ Die.addValue(DIEValueAllocator, Attribute,
EntryCU == DieCU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
Entry);
}
@@ -290,7 +294,7 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,
DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) {
assert(Tag != dwarf::DW_TAG_auto_variable &&
Tag != dwarf::DW_TAG_arg_variable);
- DIE &Die = Parent.addChild(make_unique<DIE>((dwarf::Tag)Tag));
+ DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, (dwarf::Tag)Tag));
if (N)
insertDIE(N, &Die);
return Die;
@@ -299,14 +303,15 @@ DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) {
void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) {
Loc->ComputeSize(Asm);
DIELocs.push_back(Loc); // Memoize so we can call the destructor later on.
- Die.addValue(Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc);
+ Die.addValue(DIEValueAllocator, Attribute,
+ Loc->BestForm(DD->getDwarfVersion()), Loc);
}
void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute,
DIEBlock *Block) {
Block->ComputeSize(Asm);
DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
- Die.addValue(Attribute, Block->BestForm(), Block);
+ Die.addValue(DIEValueAllocator, Attribute, Block->BestForm(), Block);
}
void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, StringRef File,
@@ -1064,6 +1069,30 @@ DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) {
return &NDie;
}
+DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
+ // Construct the context before querying for the existence of the DIE in case
+ // such construction creates the DIE.
+ DIE *ContextDIE = getOrCreateContextDIE(M->getScope());
+
+ if (DIE *MDie = getDIE(M))
+ return MDie;
+ DIE &MDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, M);
+
+ if (!M->getName().empty()) {
+ addString(MDie, dwarf::DW_AT_name, M->getName());
+ addGlobalName(M->getName(), MDie, M->getScope());
+ }
+ if (!M->getConfigurationMacros().empty())
+ addString(MDie, dwarf::DW_AT_LLVM_config_macros,
+ M->getConfigurationMacros());
+ if (!M->getIncludePath().empty())
+ addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());
+ if (!M->getISysRoot().empty())
+ addString(MDie, dwarf::DW_AT_LLVM_isysroot, M->getISysRoot());
+
+ return &MDie;
+}
+
DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, 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
@@ -1340,24 +1369,44 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
// Handle bitfield, assume bytes are 8 bits.
addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8);
addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size);
-
+ //
+ // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
+ // significant bit of the aligned storage unit containing the bit field to
+ // the most significan bit of the bit field.
+ //
+ // FIXME: DWARF 4 states that DW_AT_data_bit_offset (which
+ // counts from the beginning, regardless of endianness) should
+ // be used instead.
+ //
+ //
+ // Struct Align Align Align
+ // v v v v
+ // +-----------+-----*-----+-----*-----+--
+ // | ... |b1|b2|b3|b4|
+ // +-----------+-----*-----+-----*-----+--
+ // | | |<-- Size ->| |
+ // |<---- Offset --->| |<--->|
+ // | | | \_ DW_AT_bit_offset (little endian)
+ // | |<--->|
+ // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
+ // \ = DW_AT_data_bit_offset (biendian)
+ // \_ OffsetInBytes
uint64_t Offset = DT->getOffsetInBits();
- uint64_t AlignMask = ~(DT->getAlignInBits() - 1);
- uint64_t HiMark = (Offset + FieldSize) & AlignMask;
- uint64_t FieldOffset = (HiMark - FieldSize);
- Offset -= FieldOffset;
-
- // Maybe we need to work from the other end.
- if (Asm->getDataLayout().isLittleEndian())
- Offset = FieldSize - (Offset + Size);
- addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset);
-
- // Here DW_AT_data_member_location points to the anonymous
- // field that includes this bit field.
- OffsetInBytes = FieldOffset >> 3;
+ uint64_t Align = DT->getAlignInBits() ? DT->getAlignInBits() : FieldSize;
+ uint64_t AlignMask = ~(Align - 1);
+ // The bits from the start of the storage unit to the start of the field.
+ uint64_t StartBitOffset = Offset - (Offset & AlignMask);
+ // The endian-dependent DWARF 2 offset.
+ uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
+ ? OffsetToAlignment(Offset + Size, Align)
+ : StartBitOffset;
+
+ // The byte offset of the field's aligned storage unit inside the struct.
+ OffsetInBytes = (Offset - StartBitOffset) / 8;
+ addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
} else
// This is not a bitfield.
- OffsetInBytes = DT->getOffsetInBits() >> 3;
+ OffsetInBytes = DT->getOffsetInBits() / 8;
if (DD->getDwarfVersion() <= 2) {
DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
@@ -1386,8 +1435,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
// Objective-C properties.
if (DINode *PNode = DT->getObjCProperty())
if (DIE *PDie = getDIE(PNode))
- MemberDie.addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
- DIEEntry(*PDie));
+ MemberDie.addValue(DIEValueAllocator, dwarf::DW_AT_APPLE_property,
+ dwarf::DW_FORM_ref4, DIEEntry(*PDie));
if (DT->isArtificial())
addFlag(MemberDie, dwarf::DW_AT_artificial);
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 200ddf0..4000ae4 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -73,8 +73,11 @@ protected:
/// MDNode for the compile unit.
const DICompileUnit *CUNode;
+ // All DIEValues are allocated through this allocator.
+ BumpPtrAllocator DIEValueAllocator;
+
/// Unit debug information entry.
- DIE UnitDie;
+ DIE &UnitDie;
/// Offset of the UnitDie from beginning of debug info section.
unsigned DebugInfoOffset;
@@ -104,9 +107,6 @@ protected:
/// corresponds to the MDNode mapped with the subprogram DIE.
DenseMap<DIE *, const DINode *> ContainingTypeMap;
- // All DIEValues are allocated through this allocator.
- BumpPtrAllocator DIEValueAllocator;
-
/// The section this unit will be emitted in.
MCSection *Section;
@@ -206,8 +206,8 @@ public:
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str);
/// \brief Add a Dwarf label attribute data and value.
- void addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form,
- const MCSymbol *Label);
+ DIE::value_iterator addLabel(DIE &Die, dwarf::Attribute Attribute,
+ dwarf::Form Form, const MCSymbol *Label);
void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label);
@@ -291,6 +291,7 @@ public:
dwarf::Attribute Attribute = dwarf::DW_AT_type);
DIE *getOrCreateNameSpace(const DINamespace *NS);
+ DIE *getOrCreateModule(const DIModule *M);
DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false);
void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
@@ -402,5 +403,5 @@ public:
}
DwarfCompileUnit &getCU() override { return CU; }
};
-} // namespace llvm
+} // end llvm namespace
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
index 128a8ad..e42e082 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
@@ -30,7 +30,7 @@ template <typename T>
class SmallVectorImpl;
/// Emits exception handling directives.
-class EHStreamer : public AsmPrinterHandler {
+class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler {
protected:
/// Target of directive emission.
AsmPrinter *Asm;
@@ -132,7 +132,7 @@ public:
void beginInstruction(const MachineInstr *MI) override {}
void endInstruction() override {}
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index 802456b..2ceec61 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -58,7 +58,7 @@ static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
SymName[Letter] = toupper(SymName[Letter]);
SmallString<128> TmpStr;
- AP.Mang->getNameWithPrefix(TmpStr, SymName);
+ Mangler::getNameWithPrefix(TmpStr, SymName, M.getDataLayout());
MCSymbol *Sym = AP.OutContext.getOrCreateSymbol(TmpStr);
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
index 11bfe76..535b1f6 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
@@ -378,4 +378,4 @@ void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) {
return;
maybeRecordLocation(DL, Asm->MF);
}
-} // namespace llvm
+}
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
index c66d141..a5b399f 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
@@ -29,7 +29,7 @@
namespace llvm {
/// \brief Collects and handles line tables information in a CodeView format.
-class WinCodeViewLineTables : public AsmPrinterHandler {
+class LLVM_LIBRARY_VISIBILITY WinCodeViewLineTables : public AsmPrinterHandler {
AsmPrinter *Asm;
DebugLoc PrevInstLoc;
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 1ba6060..79830bc 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -319,6 +319,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
return;
} else {
FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName);
+ emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName);
}
MCSymbol *UnwindMapXData = nullptr;
@@ -547,28 +548,33 @@ void WinException::extendIP2StateTable(const MachineFunction *MF,
}
}
+void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
+ StringRef FLinkageName) {
+ // Outlined helpers called by the EH runtime need to know the offset of the EH
+ // registration in order to recover the parent frame pointer. Now that we know
+ // we've code generated the parent, we can emit the label assignment that
+ // those helpers use to get the offset of the registration node.
+ assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
+ "no EH reg node frameescape index");
+ MCSymbol *ParentFrameOffset =
+ Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
+ MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
+ FLinkageName, FuncInfo.EHRegNodeEscapeIndex);
+ const MCExpr *RegistrationOffsetSymRef =
+ MCSymbolRefExpr::create(RegistrationOffsetSym, Asm->OutContext);
+ Asm->OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef);
+}
+
/// Emit the language-specific data that _except_handler3 and 4 expect. This is
/// functionally equivalent to the __C_specific_handler table, except it is
/// indexed by state number instead of IP.
void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
MCStreamer &OS = *Asm->OutStreamer;
-
- // Define the EH registration node offset label in terms of its frameescape
- // label. The WinEHStatePass ensures that the registration node is passed to
- // frameescape. This allows SEH filter functions to access the
- // EXCEPTION_POINTERS field, which is filled in by the _except_handlerN.
const Function *F = MF->getFunction();
- WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
- assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
- "no EH reg node frameescape index");
StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
- MCSymbol *ParentFrameOffset =
- Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
- MCSymbol *FrameAllocSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
- FLinkageName, FuncInfo.EHRegNodeEscapeIndex);
- const MCSymbolRefExpr *FrameAllocSymRef =
- MCSymbolRefExpr::create(FrameAllocSym, Asm->OutContext);
- OS.EmitAssignment(ParentFrameOffset, FrameAllocSymRef);
+
+ WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
+ emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
// Emit the __ehtable label that we use for llvm.x86.seh.lsda.
MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h
index bbff3c2..669c9cc 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h
@@ -23,7 +23,7 @@ class MachineFunction;
class MCExpr;
struct WinEHFuncInfo;
-class WinException : public EHStreamer {
+class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
/// Per-function flag to indicate if personality info should be emitted.
bool shouldEmitPersonality = false;
@@ -50,6 +50,11 @@ class WinException : public EHStreamer {
void extendIP2StateTable(const MachineFunction *MF, const Function *ParentF,
WinEHFuncInfo &FuncInfo);
+ /// Emits the label used with llvm.x86.seh.recoverfp, which is used by
+ /// outlined funclets.
+ void emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
+ StringRef FLinkageName);
+
const MCExpr *create32bitRef(const MCSymbol *Value);
const MCExpr *create32bitRef(const GlobalValue *GV);
@@ -70,7 +75,7 @@ public:
/// Gather and emit post-function exception information.
void endFunction(const MachineFunction *) override;
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/AtomicExpandPass.cpp b/contrib/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 0bb0fa3..530ab46 100644
--- a/contrib/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/contrib/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -55,7 +55,7 @@ namespace {
bool isIdempotentRMW(AtomicRMWInst *AI);
bool simplifyIdempotentRMW(AtomicRMWInst *AI);
};
-} // namespace
+}
char AtomicExpand::ID = 0;
char &llvm::AtomicExpandID = AtomicExpand::ID;
diff --git a/contrib/llvm/lib/CodeGen/BranchFolding.cpp b/contrib/llvm/lib/CodeGen/BranchFolding.cpp
index e7b7f5b..6182667 100644
--- a/contrib/llvm/lib/CodeGen/BranchFolding.cpp
+++ b/contrib/llvm/lib/CodeGen/BranchFolding.cpp
@@ -79,7 +79,7 @@ namespace {
MachineFunctionPass::getAnalysisUsage(AU);
}
};
-} // namespace
+}
char BranchFolderPass::ID = 0;
char &llvm::BranchFolderPassID = BranchFolderPass::ID;
@@ -270,7 +270,9 @@ static unsigned HashMachineInstr(const MachineInstr *MI) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &Op = MI->getOperand(i);
- // Merge in bits from the operand if easy.
+ // Merge in bits from the operand if easy. We can't use MachineOperand's
+ // hash_code here because it's not deterministic and we sort by hash value
+ // later.
unsigned OperandHash = 0;
switch (Op.getType()) {
case MachineOperand::MO_Register:
@@ -304,17 +306,9 @@ static unsigned HashMachineInstr(const MachineInstr *MI) {
/// HashEndOfMBB - Hash the last instruction in the MBB.
static unsigned HashEndOfMBB(const MachineBasicBlock *MBB) {
- MachineBasicBlock::const_iterator I = MBB->end();
- if (I == MBB->begin())
- return 0; // Empty MBB.
-
- --I;
- // Skip debug info so it will not affect codegen.
- while (I->isDebugValue()) {
- if (I == MBB->begin())
- return 0; // MBB empty except for debug info.
- --I;
- }
+ MachineBasicBlock::const_iterator I = MBB->getLastNonDebugInstr();
+ if (I == MBB->end())
+ return 0;
return HashMachineInstr(I);
}
@@ -1123,25 +1117,15 @@ bool BranchFolder::OptimizeBranches(MachineFunction &MF) {
// Blocks should be considered empty if they contain only debug info;
// else the debug info would affect codegen.
static bool IsEmptyBlock(MachineBasicBlock *MBB) {
- if (MBB->empty())
- return true;
- for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end();
- MBBI!=MBBE; ++MBBI) {
- if (!MBBI->isDebugValue())
- return false;
- }
- return true;
+ return MBB->getFirstNonDebugInstr() == MBB->end();
}
// Blocks with only debug info and branches should be considered the same
// as blocks with only branches.
static bool IsBranchOnlyBlock(MachineBasicBlock *MBB) {
- MachineBasicBlock::iterator MBBI, MBBE;
- for (MBBI = MBB->begin(), MBBE = MBB->end(); MBBI!=MBBE; ++MBBI) {
- if (!MBBI->isDebugValue())
- break;
- }
- return (MBBI->isBranch());
+ MachineBasicBlock::iterator I = MBB->getFirstNonDebugInstr();
+ assert(I != MBB->end() && "empty block!");
+ return I->isBranch();
}
/// IsBetterFallthrough - Return true if it would be clearly better to
@@ -1154,36 +1138,24 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1,
// MBB1 doesn't, we prefer to fall through into MBB1. This allows us to
// optimize branches that branch to either a return block or an assert block
// into a fallthrough to the return.
- if (IsEmptyBlock(MBB1) || IsEmptyBlock(MBB2)) return false;
+ MachineBasicBlock::iterator MBB1I = MBB1->getLastNonDebugInstr();
+ MachineBasicBlock::iterator MBB2I = MBB2->getLastNonDebugInstr();
+ if (MBB1I == MBB1->end() || MBB2I == MBB2->end())
+ return false;
// If there is a clear successor ordering we make sure that one block
// will fall through to the next
if (MBB1->isSuccessor(MBB2)) return true;
if (MBB2->isSuccessor(MBB1)) return false;
- // Neither block consists entirely of debug info (per IsEmptyBlock check),
- // so we needn't test for falling off the beginning here.
- MachineBasicBlock::iterator MBB1I = --MBB1->end();
- while (MBB1I->isDebugValue())
- --MBB1I;
- MachineBasicBlock::iterator MBB2I = --MBB2->end();
- while (MBB2I->isDebugValue())
- --MBB2I;
return MBB2I->isCall() && !MBB1I->isCall();
}
/// getBranchDebugLoc - Find and return, if any, the DebugLoc of the branch
-/// instructions on the block. Always use the DebugLoc of the first
-/// branching instruction found unless its absent, in which case use the
-/// DebugLoc of the second if present.
+/// instructions on the block.
static DebugLoc getBranchDebugLoc(MachineBasicBlock &MBB) {
- MachineBasicBlock::iterator I = MBB.end();
- if (I == MBB.begin())
- return DebugLoc();
- --I;
- while (I->isDebugValue() && I != MBB.begin())
- --I;
- if (I->isBranch())
+ MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
+ if (I != MBB.end() && I->isBranch())
return I->getDebugLoc();
return DebugLoc();
}
@@ -1408,19 +1380,10 @@ ReoptimizeBlock:
// If the only things remaining in the block are debug info, remove these
// as well, so this will behave the same as an empty block in non-debug
// mode.
- if (!MBB->empty()) {
- bool NonDebugInfoFound = false;
- for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
- I != E; ++I) {
- if (!I->isDebugValue()) {
- NonDebugInfoFound = true;
- break;
- }
- }
- if (!NonDebugInfoFound)
- // Make the block empty, losing the debug info (we could probably
- // improve this in some cases.)
- MBB->erase(MBB->begin(), MBB->end());
+ if (IsEmptyBlock(MBB)) {
+ // Make the block empty, losing the debug info (we could probably
+ // improve this in some cases.)
+ MBB->erase(MBB->begin(), MBB->end());
}
// If this block is just an unconditional branch to CurTBB, we can
// usually completely eliminate the block. The only case we cannot
diff --git a/contrib/llvm/lib/CodeGen/BranchFolding.h b/contrib/llvm/lib/CodeGen/BranchFolding.h
index d1b17dd..46c05dc 100644
--- a/contrib/llvm/lib/CodeGen/BranchFolding.h
+++ b/contrib/llvm/lib/CodeGen/BranchFolding.h
@@ -24,7 +24,7 @@ namespace llvm {
class TargetInstrInfo;
class TargetRegisterInfo;
- class BranchFolder {
+ class LLVM_LIBRARY_VISIBILITY BranchFolder {
public:
explicit BranchFolder(bool defaultEnableTailMerge, bool CommonHoist,
const MachineBlockFrequencyInfo &MBFI,
@@ -142,6 +142,6 @@ namespace llvm {
bool HoistCommonCode(MachineFunction &MF);
bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB);
};
-} // namespace llvm
+}
#endif /* LLVM_CODEGEN_BRANCHFOLDING_HPP */
diff --git a/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp b/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 247c45b..70de4e7 100644
--- a/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/contrib/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -189,7 +189,7 @@ class TypePromotionTransaction;
bool splitBranchCondition(Function &F);
bool simplifyOffsetableRelocate(Instruction &I);
};
-} // namespace
+}
char CodeGenPrepare::ID = 0;
INITIALIZE_TM_PASS(CodeGenPrepare, "codegenprepare",
diff --git a/contrib/llvm/lib/CodeGen/CoreCLRGC.cpp b/contrib/llvm/lib/CodeGen/CoreCLRGC.cpp
index 0816d14..28c97ba 100644
--- a/contrib/llvm/lib/CodeGen/CoreCLRGC.cpp
+++ b/contrib/llvm/lib/CodeGen/CoreCLRGC.cpp
@@ -45,7 +45,7 @@ public:
return (1 == PT->getAddressSpace());
}
};
-} // namespace
+}
static GCRegistry::Add<CoreCLRGC> X("coreclr", "CoreCLR-compatible GC");
diff --git a/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.h b/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.h
index 1ca5300..10b8739 100644
--- a/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.h
+++ b/contrib/llvm/lib/CodeGen/CriticalAntiDepBreaker.h
@@ -31,7 +31,7 @@ class RegisterClassInfo;
class TargetInstrInfo;
class TargetRegisterInfo;
- class CriticalAntiDepBreaker : public AntiDepBreaker {
+class LLVM_LIBRARY_VISIBILITY CriticalAntiDepBreaker : public AntiDepBreaker {
MachineFunction& MF;
MachineRegisterInfo &MRI;
const TargetInstrInfo *TII;
@@ -103,6 +103,6 @@ class TargetRegisterInfo;
const TargetRegisterClass *RC,
SmallVectorImpl<unsigned> &Forbid);
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp b/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp
index 02cdb50..0a188c0 100644
--- a/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp
+++ b/contrib/llvm/lib/CodeGen/DFAPacketizer.cpp
@@ -110,7 +110,7 @@ public:
// Schedule - Actual scheduling work.
void schedule() override;
};
-} // namespace llvm
+}
DefaultVLIWScheduler::DefaultVLIWScheduler(MachineFunction &MF,
MachineLoopInfo &MLI, bool IsPostRA)
diff --git a/contrib/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp b/contrib/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
index efaf47c..963d573 100644
--- a/contrib/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
+++ b/contrib/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
@@ -45,7 +45,7 @@ namespace {
private:
bool isDead(const MachineInstr *MI) const;
};
-} // namespace
+}
char DeadMachineInstructionElim::ID = 0;
char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID;
diff --git a/contrib/llvm/lib/CodeGen/EdgeBundles.cpp b/contrib/llvm/lib/CodeGen/EdgeBundles.cpp
index f43b2f1..aea7c31 100644
--- a/contrib/llvm/lib/CodeGen/EdgeBundles.cpp
+++ b/contrib/llvm/lib/CodeGen/EdgeBundles.cpp
@@ -89,7 +89,7 @@ raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G,
O << "}\n";
return O;
}
-} // namespace llvm
+}
/// view - Visualize the annotated bipartite CFG with Graphviz.
void EdgeBundles::view() const {
diff --git a/contrib/llvm/lib/CodeGen/ExecutionDepsFix.cpp b/contrib/llvm/lib/CodeGen/ExecutionDepsFix.cpp
index dd508b3..5b09cf1 100644
--- a/contrib/llvm/lib/CodeGen/ExecutionDepsFix.cpp
+++ b/contrib/llvm/lib/CodeGen/ExecutionDepsFix.cpp
@@ -110,7 +110,7 @@ struct DomainValue {
Instrs.clear();
}
};
-} // namespace
+}
namespace {
/// Information about a live register.
@@ -201,7 +201,7 @@ private:
bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref);
void processUndefReads(MachineBasicBlock*);
};
-} // namespace
+}
char ExeDepsFix::ID = 0;
diff --git a/contrib/llvm/lib/CodeGen/FaultMaps.cpp b/contrib/llvm/lib/CodeGen/FaultMaps.cpp
index 0512ff9..2acafaf 100644
--- a/contrib/llvm/lib/CodeGen/FaultMaps.cpp
+++ b/contrib/llvm/lib/CodeGen/FaultMaps.cpp
@@ -112,3 +112,39 @@ const char *FaultMaps::faultTypeToString(FaultMaps::FaultKind FT) {
return "FaultingLoad";
}
}
+
+raw_ostream &llvm::
+operator<<(raw_ostream &OS,
+ const FaultMapParser::FunctionFaultInfoAccessor &FFI) {
+ OS << "Fault kind: "
+ << FaultMaps::faultTypeToString((FaultMaps::FaultKind)FFI.getFaultKind())
+ << ", faulting PC offset: " << FFI.getFaultingPCOffset()
+ << ", handling PC offset: " << FFI.getHandlerPCOffset();
+ return OS;
+}
+
+raw_ostream &llvm::
+operator<<(raw_ostream &OS, const FaultMapParser::FunctionInfoAccessor &FI) {
+ OS << "FunctionAddress: " << format_hex(FI.getFunctionAddr(), 8)
+ << ", NumFaultingPCs: " << FI.getNumFaultingPCs() << "\n";
+ for (unsigned i = 0, e = FI.getNumFaultingPCs(); i != e; ++i)
+ OS << FI.getFunctionFaultInfoAt(i) << "\n";
+ return OS;
+}
+
+raw_ostream &llvm::operator<<(raw_ostream &OS, const FaultMapParser &FMP) {
+ OS << "Version: " << format_hex(FMP.getFaultMapVersion(), 2) << "\n";
+ OS << "NumFunctions: " << FMP.getNumFunctions() << "\n";
+
+ if (FMP.getNumFunctions() == 0)
+ return OS;
+
+ FaultMapParser::FunctionInfoAccessor FI;
+
+ for (unsigned i = 0, e = FMP.getNumFunctions(); i != e; ++i) {
+ FI = (i == 0) ? FMP.getFirstFunctionInfo() : FI.getNextFunctionInfo();
+ OS << FI;
+ }
+
+ return OS;
+}
diff --git a/contrib/llvm/lib/CodeGen/GCMetadata.cpp b/contrib/llvm/lib/CodeGen/GCMetadata.cpp
index cba7f5f..c8116a4 100644
--- a/contrib/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/contrib/llvm/lib/CodeGen/GCMetadata.cpp
@@ -38,7 +38,7 @@ public:
bool runOnFunction(Function &F) override;
bool doFinalization(Module &M) override;
};
-} // namespace
+}
INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
"Create Garbage Collector Module Metadata", false, false)
diff --git a/contrib/llvm/lib/CodeGen/GCRootLowering.cpp b/contrib/llvm/lib/CodeGen/GCRootLowering.cpp
index fcef322..d8edd7e 100644
--- a/contrib/llvm/lib/CodeGen/GCRootLowering.cpp
+++ b/contrib/llvm/lib/CodeGen/GCRootLowering.cpp
@@ -76,7 +76,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
};
-} // namespace
+}
// -----------------------------------------------------------------------------
diff --git a/contrib/llvm/lib/CodeGen/IfConversion.cpp b/contrib/llvm/lib/CodeGen/IfConversion.cpp
index 963dfe7..ee0532b 100644
--- a/contrib/llvm/lib/CodeGen/IfConversion.cpp
+++ b/contrib/llvm/lib/CodeGen/IfConversion.cpp
@@ -197,8 +197,7 @@ namespace {
bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
unsigned &Dups1, unsigned &Dups2) const;
void ScanInstructions(BBInfo &BBI);
- BBInfo &AnalyzeBlock(MachineBasicBlock *BB,
- std::vector<IfcvtToken*> &Tokens);
+ void AnalyzeBlock(MachineBasicBlock *MBB, std::vector<IfcvtToken*> &Tokens);
bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
bool isTriangle = false, bool RevBranch = false);
void AnalyzeBlocks(MachineFunction &MF, std::vector<IfcvtToken*> &Tokens);
@@ -264,7 +263,7 @@ namespace {
};
char IfConverter::ID = 0;
-} // namespace
+}
char &llvm::IfConverterID = IfConverter::ID;
@@ -764,155 +763,185 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
/// AnalyzeBlock - Analyze the structure of the sub-CFG starting from
/// the specified block. Record its successors and whether it looks like an
/// if-conversion candidate.
-IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB,
- std::vector<IfcvtToken*> &Tokens) {
- BBInfo &BBI = BBAnalysis[BB->getNumber()];
+void IfConverter::AnalyzeBlock(MachineBasicBlock *MBB,
+ std::vector<IfcvtToken*> &Tokens) {
+ struct BBState {
+ BBState(MachineBasicBlock *BB) : MBB(BB), SuccsAnalyzed(false) {}
+ MachineBasicBlock *MBB;
+
+ /// This flag is true if MBB's successors have been analyzed.
+ bool SuccsAnalyzed;
+ };
- if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed)
- return BBI;
+ // Push MBB to the stack.
+ SmallVector<BBState, 16> BBStack(1, MBB);
- BBI.BB = BB;
- BBI.IsBeingAnalyzed = true;
+ while (!BBStack.empty()) {
+ BBState &State = BBStack.back();
+ MachineBasicBlock *BB = State.MBB;
+ BBInfo &BBI = BBAnalysis[BB->getNumber()];
- ScanInstructions(BBI);
+ if (!State.SuccsAnalyzed) {
+ if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
+ BBStack.pop_back();
+ continue;
+ }
- // Unanalyzable or ends with fallthrough or unconditional branch, or if is not
- // considered for ifcvt anymore.
- if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
- BBI.IsBeingAnalyzed = false;
- BBI.IsAnalyzed = true;
- return BBI;
- }
+ BBI.BB = BB;
+ BBI.IsBeingAnalyzed = true;
- // Do not ifcvt if either path is a back edge to the entry block.
- if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
- BBI.IsBeingAnalyzed = false;
- BBI.IsAnalyzed = true;
- return BBI;
- }
+ ScanInstructions(BBI);
- // Do not ifcvt if true and false fallthrough blocks are the same.
- if (!BBI.FalseBB) {
- BBI.IsBeingAnalyzed = false;
- BBI.IsAnalyzed = true;
- return BBI;
- }
+ // Unanalyzable or ends with fallthrough or unconditional branch, or if is
+ // not considered for ifcvt anymore.
+ if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
+ BBI.IsBeingAnalyzed = false;
+ BBI.IsAnalyzed = true;
+ BBStack.pop_back();
+ continue;
+ }
- BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens);
- BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens);
+ // Do not ifcvt if either path is a back edge to the entry block.
+ if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
+ BBI.IsBeingAnalyzed = false;
+ BBI.IsAnalyzed = true;
+ BBStack.pop_back();
+ continue;
+ }
- if (TrueBBI.IsDone && FalseBBI.IsDone) {
- BBI.IsBeingAnalyzed = false;
- BBI.IsAnalyzed = true;
- return BBI;
- }
+ // Do not ifcvt if true and false fallthrough blocks are the same.
+ if (!BBI.FalseBB) {
+ BBI.IsBeingAnalyzed = false;
+ BBI.IsAnalyzed = true;
+ BBStack.pop_back();
+ continue;
+ }
- SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
- bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
+ // Push the False and True blocks to the stack.
+ State.SuccsAnalyzed = true;
+ BBStack.push_back(BBI.FalseBB);
+ BBStack.push_back(BBI.TrueBB);
+ continue;
+ }
- unsigned Dups = 0;
- unsigned Dups2 = 0;
- bool TNeedSub = !TrueBBI.Predicate.empty();
- bool FNeedSub = !FalseBBI.Predicate.empty();
- bool Enqueued = false;
+ BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
+ BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
- BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);
+ if (TrueBBI.IsDone && FalseBBI.IsDone) {
+ BBI.IsBeingAnalyzed = false;
+ BBI.IsAnalyzed = true;
+ BBStack.pop_back();
+ continue;
+ }
- if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
- MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) +
- TrueBBI.ExtraCost), TrueBBI.ExtraCost2,
- *FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) +
- FalseBBI.ExtraCost),FalseBBI.ExtraCost2,
- Prediction) &&
- FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
- FeasibilityAnalysis(FalseBBI, RevCond)) {
- // Diamond:
- // EBB
- // / \_
- // | |
- // TBB FBB
- // \ /
- // TailBB
- // Note TailBB can be empty.
- Tokens.push_back(new IfcvtToken(BBI, ICDiamond, TNeedSub|FNeedSub, Dups,
- Dups2));
- Enqueued = true;
- }
+ SmallVector<MachineOperand, 4>
+ RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
+ bool CanRevCond = !TII->ReverseBranchCondition(RevCond);
- if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&
- MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
- TrueBBI.ExtraCost2, Prediction) &&
- FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
- // Triangle:
- // EBB
- // | \_
- // | |
- // | TBB
- // | /
- // FBB
- Tokens.push_back(new IfcvtToken(BBI, ICTriangle, TNeedSub, Dups));
- Enqueued = true;
- }
+ unsigned Dups = 0;
+ unsigned Dups2 = 0;
+ bool TNeedSub = !TrueBBI.Predicate.empty();
+ bool FNeedSub = !FalseBBI.Predicate.empty();
+ bool Enqueued = false;
- if (ValidTriangle(TrueBBI, FalseBBI, true, Dups, Prediction) &&
- MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
- TrueBBI.ExtraCost2, Prediction) &&
- FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
- Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
- Enqueued = true;
- }
+ BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);
- if (ValidSimple(TrueBBI, Dups, Prediction) &&
- MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
- TrueBBI.ExtraCost2, Prediction) &&
- FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
- // Simple (split, no rejoin):
- // EBB
- // | \_
- // | |
- // | TBB---> exit
- // |
- // FBB
- Tokens.push_back(new IfcvtToken(BBI, ICSimple, TNeedSub, Dups));
- Enqueued = true;
- }
+ if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
+ MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) +
+ TrueBBI.ExtraCost), TrueBBI.ExtraCost2,
+ *FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) +
+ FalseBBI.ExtraCost),FalseBBI.ExtraCost2,
+ Prediction) &&
+ FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
+ FeasibilityAnalysis(FalseBBI, RevCond)) {
+ // Diamond:
+ // EBB
+ // / \_
+ // | |
+ // TBB FBB
+ // \ /
+ // TailBB
+ // Note TailBB can be empty.
+ Tokens.push_back(new IfcvtToken(BBI, ICDiamond, TNeedSub|FNeedSub, Dups,
+ Dups2));
+ Enqueued = true;
+ }
- if (CanRevCond) {
- // Try the other path...
- if (ValidTriangle(FalseBBI, TrueBBI, false, Dups,
- Prediction.getCompl()) &&
- MeetIfcvtSizeLimit(*FalseBBI.BB,
- FalseBBI.NonPredSize + FalseBBI.ExtraCost,
- FalseBBI.ExtraCost2, Prediction.getCompl()) &&
- FeasibilityAnalysis(FalseBBI, RevCond, true)) {
- Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
+ if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&
+ MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
+ TrueBBI.ExtraCost2, Prediction) &&
+ FeasibilityAnalysis(TrueBBI, BBI.BrCond, true)) {
+ // Triangle:
+ // EBB
+ // | \_
+ // | |
+ // | TBB
+ // | /
+ // FBB
+ Tokens.push_back(new IfcvtToken(BBI, ICTriangle, TNeedSub, Dups));
Enqueued = true;
}
- if (ValidTriangle(FalseBBI, TrueBBI, true, Dups,
- Prediction.getCompl()) &&
- MeetIfcvtSizeLimit(*FalseBBI.BB,
- FalseBBI.NonPredSize + FalseBBI.ExtraCost,
- FalseBBI.ExtraCost2, Prediction.getCompl()) &&
- FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
- Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
+ if (ValidTriangle(TrueBBI, FalseBBI, true, Dups, Prediction) &&
+ MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
+ TrueBBI.ExtraCost2, Prediction) &&
+ FeasibilityAnalysis(TrueBBI, BBI.BrCond, true, true)) {
+ Tokens.push_back(new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
Enqueued = true;
}
- if (ValidSimple(FalseBBI, Dups, Prediction.getCompl()) &&
- MeetIfcvtSizeLimit(*FalseBBI.BB,
- FalseBBI.NonPredSize + FalseBBI.ExtraCost,
- FalseBBI.ExtraCost2, Prediction.getCompl()) &&
- FeasibilityAnalysis(FalseBBI, RevCond)) {
- Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
+ if (ValidSimple(TrueBBI, Dups, Prediction) &&
+ MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
+ TrueBBI.ExtraCost2, Prediction) &&
+ FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
+ // Simple (split, no rejoin):
+ // EBB
+ // | \_
+ // | |
+ // | TBB---> exit
+ // |
+ // FBB
+ Tokens.push_back(new IfcvtToken(BBI, ICSimple, TNeedSub, Dups));
Enqueued = true;
}
- }
- BBI.IsEnqueued = Enqueued;
- BBI.IsBeingAnalyzed = false;
- BBI.IsAnalyzed = true;
- return BBI;
+ if (CanRevCond) {
+ // Try the other path...
+ if (ValidTriangle(FalseBBI, TrueBBI, false, Dups,
+ Prediction.getCompl()) &&
+ MeetIfcvtSizeLimit(*FalseBBI.BB,
+ FalseBBI.NonPredSize + FalseBBI.ExtraCost,
+ FalseBBI.ExtraCost2, Prediction.getCompl()) &&
+ FeasibilityAnalysis(FalseBBI, RevCond, true)) {
+ Tokens.push_back(new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
+ Enqueued = true;
+ }
+
+ if (ValidTriangle(FalseBBI, TrueBBI, true, Dups,
+ Prediction.getCompl()) &&
+ MeetIfcvtSizeLimit(*FalseBBI.BB,
+ FalseBBI.NonPredSize + FalseBBI.ExtraCost,
+ FalseBBI.ExtraCost2, Prediction.getCompl()) &&
+ FeasibilityAnalysis(FalseBBI, RevCond, true, true)) {
+ Tokens.push_back(new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
+ Enqueued = true;
+ }
+
+ if (ValidSimple(FalseBBI, Dups, Prediction.getCompl()) &&
+ MeetIfcvtSizeLimit(*FalseBBI.BB,
+ FalseBBI.NonPredSize + FalseBBI.ExtraCost,
+ FalseBBI.ExtraCost2, Prediction.getCompl()) &&
+ FeasibilityAnalysis(FalseBBI, RevCond)) {
+ Tokens.push_back(new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
+ Enqueued = true;
+ }
+ }
+
+ BBI.IsEnqueued = Enqueued;
+ BBI.IsBeingAnalyzed = false;
+ BBI.IsAnalyzed = true;
+ BBStack.pop_back();
+ }
}
/// AnalyzeBlocks - Analyze all blocks and find entries for all if-conversion
@@ -1355,15 +1384,9 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
Redefs.addLiveIns(BBI1->BB);
// Remove the duplicated instructions at the beginnings of both paths.
- MachineBasicBlock::iterator DI1 = BBI1->BB->begin();
- MachineBasicBlock::iterator DI2 = BBI2->BB->begin();
- MachineBasicBlock::iterator DIE1 = BBI1->BB->end();
- MachineBasicBlock::iterator DIE2 = BBI2->BB->end();
// Skip dbg_value instructions
- while (DI1 != DIE1 && DI1->isDebugValue())
- ++DI1;
- while (DI2 != DIE2 && DI2->isDebugValue())
- ++DI2;
+ MachineBasicBlock::iterator DI1 = BBI1->BB->getFirstNonDebugInstr();
+ MachineBasicBlock::iterator DI2 = BBI2->BB->getFirstNonDebugInstr();
BBI1->NonPredSize -= NumDups1;
BBI2->NonPredSize -= NumDups1;
diff --git a/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp b/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp
index b1176ce..a02cd67 100644
--- a/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp
+++ b/contrib/llvm/lib/CodeGen/ImplicitNullChecks.cpp
@@ -99,7 +99,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
};
-} // namespace
+}
bool ImplicitNullChecks::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getSubtarget().getInstrInfo();
@@ -124,6 +124,13 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks(
MachineBasicBlock &MBB, SmallVectorImpl<NullCheck> &NullCheckList) {
typedef TargetInstrInfo::MachineBranchPredicate MachineBranchPredicate;
+ MDNode *BranchMD =
+ MBB.getBasicBlock()
+ ? MBB.getBasicBlock()->getTerminator()->getMetadata("make.implicit")
+ : nullptr;
+ if (!BranchMD)
+ return false;
+
MachineBranchPredicate MBP;
if (TII->AnalyzeBranchPredicate(MBB, MBP, true))
diff --git a/contrib/llvm/lib/CodeGen/InlineSpiller.cpp b/contrib/llvm/lib/CodeGen/InlineSpiller.cpp
index 48c95c9..9989f23 100644
--- a/contrib/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/contrib/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -181,7 +181,7 @@ private:
void spillAroundUses(unsigned Reg);
void spillAll();
};
-} // namespace
+}
namespace llvm {
@@ -194,7 +194,7 @@ Spiller *createInlineSpiller(MachineFunctionPass &pass,
return new InlineSpiller(pass, mf, vrm);
}
-} // namespace llvm
+}
//===----------------------------------------------------------------------===//
// Snippets
diff --git a/contrib/llvm/lib/CodeGen/InterferenceCache.h b/contrib/llvm/lib/CodeGen/InterferenceCache.h
index 6519a80..18aa5c7 100644
--- a/contrib/llvm/lib/CodeGen/InterferenceCache.h
+++ b/contrib/llvm/lib/CodeGen/InterferenceCache.h
@@ -21,7 +21,7 @@ namespace llvm {
class LiveIntervals;
-class InterferenceCache {
+class LLVM_LIBRARY_VISIBILITY InterferenceCache {
const TargetRegisterInfo *TRI;
LiveIntervalUnion *LIUArray;
MachineFunction *MF;
diff --git a/contrib/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/contrib/llvm/lib/CodeGen/InterleavedAccessPass.cpp
new file mode 100644
index 0000000..53c8adc
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/InterleavedAccessPass.cpp
@@ -0,0 +1,286 @@
+//=----------------------- InterleavedAccessPass.cpp -----------------------==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Interleaved Access pass, which identifies
+// interleaved memory accesses and transforms into target specific intrinsics.
+//
+// An interleaved load reads data from memory into several vectors, with
+// DE-interleaving the data on a factor. An interleaved store writes several
+// vectors to memory with RE-interleaving the data on a factor.
+//
+// As interleaved accesses are hard to be identified in CodeGen (mainly because
+// the VECTOR_SHUFFLE DAG node is quite different from the shufflevector IR),
+// we identify and transform them to intrinsics in this pass. So the intrinsics
+// can be easily matched into target specific instructions later in CodeGen.
+//
+// E.g. An interleaved load (Factor = 2):
+// %wide.vec = load <8 x i32>, <8 x i32>* %ptr
+// %v0 = shuffle <8 x i32> %wide.vec, <8 x i32> undef, <0, 2, 4, 6>
+// %v1 = shuffle <8 x i32> %wide.vec, <8 x i32> undef, <1, 3, 5, 7>
+//
+// It could be transformed into a ld2 intrinsic in AArch64 backend or a vld2
+// intrinsic in ARM backend.
+//
+// E.g. An interleaved store (Factor = 3):
+// %i.vec = shuffle <8 x i32> %v0, <8 x i32> %v1,
+// <0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11>
+// store <12 x i32> %i.vec, <12 x i32>* %ptr
+//
+// It could be transformed into a st3 intrinsic in AArch64 backend or a vst3
+// intrinsic in ARM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "interleaved-access"
+
+static cl::opt<bool> LowerInterleavedAccesses(
+ "lower-interleaved-accesses",
+ cl::desc("Enable lowering interleaved accesses to intrinsics"),
+ cl::init(false), cl::Hidden);
+
+static unsigned MaxFactor; // The maximum supported interleave factor.
+
+namespace llvm {
+static void initializeInterleavedAccessPass(PassRegistry &);
+}
+
+namespace {
+
+class InterleavedAccess : public FunctionPass {
+
+public:
+ static char ID;
+ InterleavedAccess(const TargetMachine *TM = nullptr)
+ : FunctionPass(ID), TM(TM), TLI(nullptr) {
+ initializeInterleavedAccessPass(*PassRegistry::getPassRegistry());
+ }
+
+ const char *getPassName() const override { return "Interleaved Access Pass"; }
+
+ bool runOnFunction(Function &F) override;
+
+private:
+ const TargetMachine *TM;
+ const TargetLowering *TLI;
+
+ /// \brief Transform an interleaved load into target specific intrinsics.
+ bool lowerInterleavedLoad(LoadInst *LI,
+ SmallVector<Instruction *, 32> &DeadInsts);
+
+ /// \brief Transform an interleaved store into target specific intrinsics.
+ bool lowerInterleavedStore(StoreInst *SI,
+ SmallVector<Instruction *, 32> &DeadInsts);
+};
+} // end anonymous namespace.
+
+char InterleavedAccess::ID = 0;
+INITIALIZE_TM_PASS(InterleavedAccess, "interleaved-access",
+ "Lower interleaved memory accesses to target specific intrinsics",
+ false, false)
+
+FunctionPass *llvm::createInterleavedAccessPass(const TargetMachine *TM) {
+ return new InterleavedAccess(TM);
+}
+
+/// \brief Check if the mask is a DE-interleave mask of the given factor
+/// \p Factor like:
+/// <Index, Index+Factor, ..., Index+(NumElts-1)*Factor>
+static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor,
+ unsigned &Index) {
+ // Check all potential start indices from 0 to (Factor - 1).
+ for (Index = 0; Index < Factor; Index++) {
+ unsigned i = 0;
+
+ // Check that elements are in ascending order by Factor. Ignore undef
+ // elements.
+ for (; i < Mask.size(); i++)
+ if (Mask[i] >= 0 && static_cast<unsigned>(Mask[i]) != Index + i * Factor)
+ break;
+
+ if (i == Mask.size())
+ return true;
+ }
+
+ return false;
+}
+
+/// \brief Check if the mask is a DE-interleave mask for an interleaved load.
+///
+/// E.g. DE-interleave masks (Factor = 2) could be:
+/// <0, 2, 4, 6> (mask of index 0 to extract even elements)
+/// <1, 3, 5, 7> (mask of index 1 to extract odd elements)
+static bool isDeInterleaveMask(ArrayRef<int> Mask, unsigned &Factor,
+ unsigned &Index) {
+ if (Mask.size() < 2)
+ return false;
+
+ // Check potential Factors.
+ for (Factor = 2; Factor <= MaxFactor; Factor++)
+ if (isDeInterleaveMaskOfFactor(Mask, Factor, Index))
+ return true;
+
+ return false;
+}
+
+/// \brief Check if the mask is RE-interleave mask for an interleaved store.
+///
+/// I.e. <0, NumSubElts, ... , NumSubElts*(Factor - 1), 1, NumSubElts + 1, ...>
+///
+/// E.g. The RE-interleave mask (Factor = 2) could be:
+/// <0, 4, 1, 5, 2, 6, 3, 7>
+static bool isReInterleaveMask(ArrayRef<int> Mask, unsigned &Factor) {
+ unsigned NumElts = Mask.size();
+ if (NumElts < 4)
+ return false;
+
+ // Check potential Factors.
+ for (Factor = 2; Factor <= MaxFactor; Factor++) {
+ if (NumElts % Factor)
+ continue;
+
+ unsigned NumSubElts = NumElts / Factor;
+ if (!isPowerOf2_32(NumSubElts))
+ continue;
+
+ // Check whether each element matchs the RE-interleaved rule. Ignore undef
+ // elements.
+ unsigned i = 0;
+ for (; i < NumElts; i++)
+ if (Mask[i] >= 0 &&
+ static_cast<unsigned>(Mask[i]) !=
+ (i % Factor) * NumSubElts + i / Factor)
+ break;
+
+ // Find a RE-interleaved mask of current factor.
+ if (i == NumElts)
+ return true;
+ }
+
+ return false;
+}
+
+bool InterleavedAccess::lowerInterleavedLoad(
+ LoadInst *LI, SmallVector<Instruction *, 32> &DeadInsts) {
+ if (!LI->isSimple())
+ return false;
+
+ SmallVector<ShuffleVectorInst *, 4> Shuffles;
+
+ // Check if all users of this load are shufflevectors.
+ for (auto UI = LI->user_begin(), E = LI->user_end(); UI != E; UI++) {
+ ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(*UI);
+ if (!SVI || !isa<UndefValue>(SVI->getOperand(1)))
+ return false;
+
+ Shuffles.push_back(SVI);
+ }
+
+ if (Shuffles.empty())
+ return false;
+
+ unsigned Factor, Index;
+
+ // Check if the first shufflevector is DE-interleave shuffle.
+ if (!isDeInterleaveMask(Shuffles[0]->getShuffleMask(), Factor, Index))
+ return false;
+
+ // Holds the corresponding index for each DE-interleave shuffle.
+ SmallVector<unsigned, 4> Indices;
+ Indices.push_back(Index);
+
+ Type *VecTy = Shuffles[0]->getType();
+
+ // Check if other shufflevectors are also DE-interleaved of the same type
+ // and factor as the first shufflevector.
+ for (unsigned i = 1; i < Shuffles.size(); i++) {
+ if (Shuffles[i]->getType() != VecTy)
+ return false;
+
+ if (!isDeInterleaveMaskOfFactor(Shuffles[i]->getShuffleMask(), Factor,
+ Index))
+ return false;
+
+ Indices.push_back(Index);
+ }
+
+ DEBUG(dbgs() << "IA: Found an interleaved load: " << *LI << "\n");
+
+ // Try to create target specific intrinsics to replace the load and shuffles.
+ if (!TLI->lowerInterleavedLoad(LI, Shuffles, Indices, Factor))
+ return false;
+
+ for (auto SVI : Shuffles)
+ DeadInsts.push_back(SVI);
+
+ DeadInsts.push_back(LI);
+ return true;
+}
+
+bool InterleavedAccess::lowerInterleavedStore(
+ StoreInst *SI, SmallVector<Instruction *, 32> &DeadInsts) {
+ if (!SI->isSimple())
+ return false;
+
+ ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(SI->getValueOperand());
+ if (!SVI || !SVI->hasOneUse())
+ return false;
+
+ // Check if the shufflevector is RE-interleave shuffle.
+ unsigned Factor;
+ if (!isReInterleaveMask(SVI->getShuffleMask(), Factor))
+ return false;
+
+ DEBUG(dbgs() << "IA: Found an interleaved store: " << *SI << "\n");
+
+ // Try to create target specific intrinsics to replace the store and shuffle.
+ if (!TLI->lowerInterleavedStore(SI, SVI, Factor))
+ return false;
+
+ // Already have a new target specific interleaved store. Erase the old store.
+ DeadInsts.push_back(SI);
+ DeadInsts.push_back(SVI);
+ return true;
+}
+
+bool InterleavedAccess::runOnFunction(Function &F) {
+ if (!TM || !LowerInterleavedAccesses)
+ return false;
+
+ DEBUG(dbgs() << "*** " << getPassName() << ": " << F.getName() << "\n");
+
+ TLI = TM->getSubtargetImpl(F)->getTargetLowering();
+ MaxFactor = TLI->getMaxSupportedInterleaveFactor();
+
+ // Holds dead instructions that will be erased later.
+ SmallVector<Instruction *, 32> DeadInsts;
+ bool Changed = false;
+
+ for (auto &I : inst_range(F)) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(&I))
+ Changed |= lowerInterleavedLoad(LI, DeadInsts);
+
+ if (StoreInst *SI = dyn_cast<StoreInst>(&I))
+ Changed |= lowerInterleavedStore(SI, DeadInsts);
+ }
+
+ for (auto I : DeadInsts)
+ I->eraseFromParent();
+
+ return Changed;
+}
diff --git a/contrib/llvm/lib/CodeGen/LiveDebugVariables.h b/contrib/llvm/lib/CodeGen/LiveDebugVariables.h
index ac2d1a1..694aa17 100644
--- a/contrib/llvm/lib/CodeGen/LiveDebugVariables.h
+++ b/contrib/llvm/lib/CodeGen/LiveDebugVariables.h
@@ -31,7 +31,7 @@ class LiveInterval;
class LiveIntervals;
class VirtRegMap;
-class LiveDebugVariables : public MachineFunctionPass {
+class LLVM_LIBRARY_VISIBILITY LiveDebugVariables : public MachineFunctionPass {
void *pImpl;
DenseMap<const Function *, DISubprogram *> FunctionDIs;
diff --git a/contrib/llvm/lib/CodeGen/LivePhysRegs.cpp b/contrib/llvm/lib/CodeGen/LivePhysRegs.cpp
index eef7643..cbd98e3 100644
--- a/contrib/llvm/lib/CodeGen/LivePhysRegs.cpp
+++ b/contrib/llvm/lib/CodeGen/LivePhysRegs.cpp
@@ -14,6 +14,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -123,3 +125,42 @@ void LivePhysRegs::dump() const {
dbgs() << " " << *this;
#endif
}
+
+/// Add live-in registers of basic block \p MBB to \p LiveRegs.
+static void addLiveIns(LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB) {
+ for (unsigned Reg : make_range(MBB.livein_begin(), MBB.livein_end()))
+ LiveRegs.addReg(Reg);
+}
+
+/// Add pristine registers to the given \p LiveRegs. This function removes
+/// actually saved callee save registers when \p InPrologueEpilogue is false.
+static void addPristines(LivePhysRegs &LiveRegs, const MachineFunction &MF,
+ const TargetRegisterInfo &TRI) {
+ const MachineFrameInfo &MFI = *MF.getFrameInfo();
+ if (!MFI.isCalleeSavedInfoValid())
+ return;
+
+ for (const MCPhysReg *CSR = TRI.getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
+ LiveRegs.addReg(*CSR);
+ for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
+ LiveRegs.removeReg(Info.getReg());
+}
+
+void LivePhysRegs::addLiveOuts(const MachineBasicBlock *MBB,
+ bool AddPristines) {
+ if (AddPristines) {
+ const MachineFunction &MF = *MBB->getParent();
+ addPristines(*this, MF, *TRI);
+ }
+ for (const MachineBasicBlock *Succ : MBB->successors())
+ ::addLiveIns(*this, *Succ);
+}
+
+void LivePhysRegs::addLiveIns(const MachineBasicBlock *MBB,
+ bool AddPristines) {
+ if (AddPristines) {
+ const MachineFunction &MF = *MBB->getParent();
+ addPristines(*this, MF, *TRI);
+ }
+ ::addLiveIns(*this, *MBB);
+}
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
new file mode 100644
index 0000000..e9b3916
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -0,0 +1,199 @@
+//===- MILexer.cpp - Machine instructions lexer implementation ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the lexing of machine instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MILexer.h"
+#include "llvm/ADT/Twine.h"
+#include <cctype>
+
+using namespace llvm;
+
+namespace {
+
+/// This class provides a way to iterate and get characters from the source
+/// string.
+class Cursor {
+ const char *Ptr;
+ const char *End;
+
+public:
+ Cursor(NoneType) : Ptr(nullptr), End(nullptr) {}
+
+ explicit Cursor(StringRef Str) {
+ Ptr = Str.data();
+ End = Ptr + Str.size();
+ }
+
+ bool isEOF() const { return Ptr == End; }
+
+ char peek(int I = 0) const { return End - Ptr <= I ? 0 : Ptr[I]; }
+
+ void advance(unsigned I = 1) { Ptr += I; }
+
+ StringRef remaining() const { return StringRef(Ptr, End - Ptr); }
+
+ StringRef upto(Cursor C) const {
+ assert(C.Ptr >= Ptr && C.Ptr <= End);
+ return StringRef(Ptr, C.Ptr - Ptr);
+ }
+
+ StringRef::iterator location() const { return Ptr; }
+
+ operator bool() const { return Ptr != nullptr; }
+};
+
+} // end anonymous namespace
+
+/// Skip the leading whitespace characters and return the updated cursor.
+static Cursor skipWhitespace(Cursor C) {
+ while (isspace(C.peek()))
+ C.advance();
+ return C;
+}
+
+static bool isIdentifierChar(char C) {
+ return isalpha(C) || isdigit(C) || C == '_' || C == '-' || C == '.';
+}
+
+static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) {
+ if (!isalpha(C.peek()) && C.peek() != '_')
+ return None;
+ auto Range = C;
+ while (isIdentifierChar(C.peek()))
+ C.advance();
+ auto Identifier = Range.upto(C);
+ Token = MIToken(Identifier == "_" ? MIToken::underscore : MIToken::Identifier,
+ Identifier);
+ return C;
+}
+
+static Cursor maybeLexMachineBasicBlock(
+ Cursor C, MIToken &Token,
+ function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
+ if (!C.remaining().startswith("%bb."))
+ return None;
+ auto Range = C;
+ C.advance(4); // Skip '%bb.'
+ if (!isdigit(C.peek())) {
+ Token = MIToken(MIToken::Error, C.remaining());
+ ErrorCallback(C.location(), "expected a number after '%bb.'");
+ return C;
+ }
+ auto NumberRange = C;
+ while (isdigit(C.peek()))
+ C.advance();
+ StringRef Number = NumberRange.upto(C);
+ unsigned StringOffset = 4 + Number.size(); // Drop '%bb.<id>'
+ if (C.peek() == '.') {
+ C.advance(); // Skip '.'
+ ++StringOffset;
+ while (isIdentifierChar(C.peek()))
+ C.advance();
+ }
+ Token = MIToken(MIToken::MachineBasicBlock, Range.upto(C), APSInt(Number),
+ StringOffset);
+ return C;
+}
+
+static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
+ if (C.peek() != '%')
+ return None;
+ auto Range = C;
+ C.advance(); // Skip '%'
+ while (isIdentifierChar(C.peek()))
+ C.advance();
+ Token = MIToken(MIToken::NamedRegister, Range.upto(C),
+ /*StringOffset=*/1); // Drop the '%'
+ return C;
+}
+
+static Cursor maybeLexGlobalValue(Cursor C, MIToken &Token) {
+ if (C.peek() != '@')
+ return None;
+ auto Range = C;
+ C.advance(); // Skip the '@'
+ // TODO: add support for quoted names.
+ if (!isdigit(C.peek())) {
+ while (isIdentifierChar(C.peek()))
+ C.advance();
+ Token = MIToken(MIToken::NamedGlobalValue, Range.upto(C),
+ /*StringOffset=*/1); // Drop the '@'
+ return C;
+ }
+ auto NumberRange = C;
+ while (isdigit(C.peek()))
+ C.advance();
+ Token =
+ MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C)));
+ return C;
+}
+
+static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) {
+ if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1))))
+ return None;
+ auto Range = C;
+ C.advance();
+ while (isdigit(C.peek()))
+ C.advance();
+ StringRef StrVal = Range.upto(C);
+ Token = MIToken(MIToken::IntegerLiteral, StrVal, APSInt(StrVal));
+ return C;
+}
+
+static MIToken::TokenKind symbolToken(char C) {
+ switch (C) {
+ case ',':
+ return MIToken::comma;
+ case '=':
+ return MIToken::equal;
+ default:
+ return MIToken::Error;
+ }
+}
+
+static Cursor maybeLexSymbol(Cursor C, MIToken &Token) {
+ auto Kind = symbolToken(C.peek());
+ if (Kind == MIToken::Error)
+ return None;
+ auto Range = C;
+ C.advance();
+ Token = MIToken(Kind, Range.upto(C));
+ return C;
+}
+
+StringRef llvm::lexMIToken(
+ StringRef Source, MIToken &Token,
+ function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
+ auto C = skipWhitespace(Cursor(Source));
+ if (C.isEOF()) {
+ Token = MIToken(MIToken::Eof, C.remaining());
+ return C.remaining();
+ }
+
+ if (Cursor R = maybeLexIdentifier(C, Token))
+ return R.remaining();
+ if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback))
+ return R.remaining();
+ if (Cursor R = maybeLexRegister(C, Token))
+ return R.remaining();
+ if (Cursor R = maybeLexGlobalValue(C, Token))
+ return R.remaining();
+ if (Cursor R = maybeLexIntegerLiteral(C, Token))
+ return R.remaining();
+ if (Cursor R = maybeLexSymbol(C, Token))
+ return R.remaining();
+
+ Token = MIToken(MIToken::Error, C.remaining());
+ ErrorCallback(C.location(),
+ Twine("unexpected character '") + Twine(C.peek()) + "'");
+ return C.remaining();
+}
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
new file mode 100644
index 0000000..c28935f
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -0,0 +1,96 @@
+//===- MILexer.h - Lexer for machine instructions -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the function that lexes the machine instruction source
+// string.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
+#define LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include <functional>
+
+namespace llvm {
+
+class Twine;
+
+/// A token produced by the machine instruction lexer.
+struct MIToken {
+ enum TokenKind {
+ // Markers
+ Eof,
+ Error,
+
+ // Tokens with no info.
+ comma,
+ equal,
+ underscore,
+
+ // Identifier tokens
+ Identifier,
+ NamedRegister,
+ MachineBasicBlock,
+ NamedGlobalValue,
+ GlobalValue,
+
+ // Other tokens
+ IntegerLiteral
+ };
+
+private:
+ TokenKind Kind;
+ unsigned StringOffset;
+ StringRef Range;
+ APSInt IntVal;
+
+public:
+ MIToken(TokenKind Kind, StringRef Range, unsigned StringOffset = 0)
+ : Kind(Kind), StringOffset(StringOffset), Range(Range) {}
+
+ MIToken(TokenKind Kind, StringRef Range, const APSInt &IntVal,
+ unsigned StringOffset = 0)
+ : Kind(Kind), StringOffset(StringOffset), Range(Range), IntVal(IntVal) {}
+
+ TokenKind kind() const { return Kind; }
+
+ bool isError() const { return Kind == Error; }
+
+ bool isRegister() const {
+ return Kind == NamedRegister || Kind == underscore;
+ }
+
+ bool is(TokenKind K) const { return Kind == K; }
+
+ bool isNot(TokenKind K) const { return Kind != K; }
+
+ StringRef::iterator location() const { return Range.begin(); }
+
+ StringRef stringValue() const { return Range.drop_front(StringOffset); }
+
+ const APSInt &integerValue() const { return IntVal; }
+
+ bool hasIntegerValue() const {
+ return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
+ Kind == GlobalValue;
+ }
+};
+
+/// Consume a single machine instruction token in the given source and return
+/// the remaining source string.
+StringRef lexMIToken(
+ StringRef Source, MIToken &Token,
+ function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
new file mode 100644
index 0000000..b618e53
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -0,0 +1,423 @@
+//===- MIParser.cpp - Machine instructions parser implementation ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the parsing of machine instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MIParser.h"
+#include "MILexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/AsmParser/SlotMapping.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
+
+using namespace llvm;
+
+namespace {
+
+class MIParser {
+ SourceMgr &SM;
+ MachineFunction &MF;
+ SMDiagnostic &Error;
+ StringRef Source, CurrentSource;
+ MIToken Token;
+ /// Maps from basic block numbers to MBBs.
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots;
+ /// Maps from indices to unnamed global values and metadata nodes.
+ const SlotMapping &IRSlots;
+ /// Maps from instruction names to op codes.
+ StringMap<unsigned> Names2InstrOpCodes;
+ /// Maps from register names to registers.
+ StringMap<unsigned> Names2Regs;
+ /// Maps from register mask names to register masks.
+ StringMap<const uint32_t *> Names2RegMasks;
+
+public:
+ MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
+ StringRef Source,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots);
+
+ void lex();
+
+ /// Report an error at the current location with the given message.
+ ///
+ /// This function always return true.
+ bool error(const Twine &Msg);
+
+ /// Report an error at the given location with the given message.
+ ///
+ /// This function always return true.
+ bool error(StringRef::iterator Loc, const Twine &Msg);
+
+ bool parse(MachineInstr *&MI);
+ bool parseMBB(MachineBasicBlock *&MBB);
+
+ bool parseRegister(unsigned &Reg);
+ bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false);
+ bool parseImmediateOperand(MachineOperand &Dest);
+ bool parseMBBReference(MachineBasicBlock *&MBB);
+ bool parseMBBOperand(MachineOperand &Dest);
+ bool parseGlobalAddressOperand(MachineOperand &Dest);
+ bool parseMachineOperand(MachineOperand &Dest);
+
+private:
+ /// Convert the integer literal in the current token into an unsigned integer.
+ ///
+ /// Return true if an error occurred.
+ bool getUnsigned(unsigned &Result);
+
+ void initNames2InstrOpCodes();
+
+ /// Try to convert an instruction name to an opcode. Return true if the
+ /// instruction name is invalid.
+ bool parseInstrName(StringRef InstrName, unsigned &OpCode);
+
+ bool parseInstruction(unsigned &OpCode);
+
+ void initNames2Regs();
+
+ /// Try to convert a register name to a register number. Return true if the
+ /// register name is invalid.
+ bool getRegisterByName(StringRef RegName, unsigned &Reg);
+
+ void initNames2RegMasks();
+
+ /// Check if the given identifier is a name of a register mask.
+ ///
+ /// Return null if the identifier isn't a register mask.
+ const uint32_t *getRegMask(StringRef Identifier);
+};
+
+} // end anonymous namespace
+
+MIParser::MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
+ StringRef Source,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots)
+ : SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source),
+ Token(MIToken::Error, StringRef()), MBBSlots(MBBSlots), IRSlots(IRSlots) {
+}
+
+void MIParser::lex() {
+ CurrentSource = lexMIToken(
+ CurrentSource, Token,
+ [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
+}
+
+bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); }
+
+bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
+ // TODO: Get the proper location in the MIR file, not just a location inside
+ // the string.
+ assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
+ Error = SMDiagnostic(
+ SM, SMLoc(),
+ SM.getMemoryBuffer(SM.getMainFileID())->getBufferIdentifier(), 1,
+ Loc - Source.data(), SourceMgr::DK_Error, Msg.str(), Source, None, None);
+ return true;
+}
+
+bool MIParser::parse(MachineInstr *&MI) {
+ lex();
+
+ // Parse any register operands before '='
+ // TODO: Allow parsing of multiple operands before '='
+ MachineOperand MO = MachineOperand::CreateImm(0);
+ SmallVector<MachineOperand, 8> Operands;
+ if (Token.isRegister()) {
+ if (parseRegisterOperand(MO, /*IsDef=*/true))
+ return true;
+ Operands.push_back(MO);
+ if (Token.isNot(MIToken::equal))
+ return error("expected '='");
+ lex();
+ }
+
+ unsigned OpCode;
+ if (Token.isError() || parseInstruction(OpCode))
+ return true;
+
+ // TODO: Parse the instruction flags and memory operands.
+
+ // Parse the remaining machine operands.
+ while (Token.isNot(MIToken::Eof)) {
+ if (parseMachineOperand(MO))
+ return true;
+ Operands.push_back(MO);
+ if (Token.is(MIToken::Eof))
+ break;
+ if (Token.isNot(MIToken::comma))
+ return error("expected ',' before the next machine operand");
+ lex();
+ }
+
+ const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode);
+
+ // Verify machine operands.
+ if (!MCID.isVariadic()) {
+ for (size_t I = 0, E = Operands.size(); I < E; ++I) {
+ if (I < MCID.getNumOperands())
+ continue;
+ // Mark this register as implicit to prevent an assertion when it's added
+ // to an instruction. This is a temporary workaround until the implicit
+ // register flag can be parsed.
+ if (Operands[I].isReg())
+ Operands[I].setImplicit();
+ }
+ }
+
+ // TODO: Determine the implicit behaviour when implicit register flags are
+ // parsed.
+ MI = MF.CreateMachineInstr(MCID, DebugLoc(), /*NoImplicit=*/true);
+ for (const auto &Operand : Operands)
+ MI->addOperand(MF, Operand);
+ return false;
+}
+
+bool MIParser::parseMBB(MachineBasicBlock *&MBB) {
+ lex();
+ if (Token.isNot(MIToken::MachineBasicBlock))
+ return error("expected a machine basic block reference");
+ if (parseMBBReference(MBB))
+ return true;
+ lex();
+ if (Token.isNot(MIToken::Eof))
+ return error(
+ "expected end of string after the machine basic block reference");
+ return false;
+}
+
+bool MIParser::parseInstruction(unsigned &OpCode) {
+ if (Token.isNot(MIToken::Identifier))
+ return error("expected a machine instruction");
+ StringRef InstrName = Token.stringValue();
+ if (parseInstrName(InstrName, OpCode))
+ return error(Twine("unknown machine instruction name '") + InstrName + "'");
+ lex();
+ return false;
+}
+
+bool MIParser::parseRegister(unsigned &Reg) {
+ switch (Token.kind()) {
+ case MIToken::underscore:
+ Reg = 0;
+ break;
+ case MIToken::NamedRegister: {
+ StringRef Name = Token.stringValue();
+ if (getRegisterByName(Name, Reg))
+ return error(Twine("unknown register name '") + Name + "'");
+ break;
+ }
+ // TODO: Parse other register kinds.
+ default:
+ llvm_unreachable("The current token should be a register");
+ }
+ return false;
+}
+
+bool MIParser::parseRegisterOperand(MachineOperand &Dest, bool IsDef) {
+ unsigned Reg;
+ // TODO: Parse register flags.
+ if (parseRegister(Reg))
+ return true;
+ lex();
+ // TODO: Parse subregister.
+ Dest = MachineOperand::CreateReg(Reg, IsDef);
+ return false;
+}
+
+bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
+ assert(Token.is(MIToken::IntegerLiteral));
+ const APSInt &Int = Token.integerValue();
+ if (Int.getMinSignedBits() > 64)
+ // TODO: Replace this with an error when we can parse CIMM Machine Operands.
+ llvm_unreachable("Can't parse large integer literals yet!");
+ Dest = MachineOperand::CreateImm(Int.getExtValue());
+ lex();
+ return false;
+}
+
+bool MIParser::getUnsigned(unsigned &Result) {
+ assert(Token.hasIntegerValue() && "Expected a token with an integer value");
+ const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
+ uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
+ if (Val64 == Limit)
+ return error("expected 32-bit integer (too large)");
+ Result = Val64;
+ return false;
+}
+
+bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
+ assert(Token.is(MIToken::MachineBasicBlock));
+ unsigned Number;
+ if (getUnsigned(Number))
+ return true;
+ auto MBBInfo = MBBSlots.find(Number);
+ if (MBBInfo == MBBSlots.end())
+ return error(Twine("use of undefined machine basic block #") +
+ Twine(Number));
+ MBB = MBBInfo->second;
+ if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
+ return error(Twine("the name of machine basic block #") + Twine(Number) +
+ " isn't '" + Token.stringValue() + "'");
+ return false;
+}
+
+bool MIParser::parseMBBOperand(MachineOperand &Dest) {
+ MachineBasicBlock *MBB;
+ if (parseMBBReference(MBB))
+ return true;
+ Dest = MachineOperand::CreateMBB(MBB);
+ lex();
+ return false;
+}
+
+bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
+ switch (Token.kind()) {
+ case MIToken::NamedGlobalValue: {
+ auto Name = Token.stringValue();
+ const Module *M = MF.getFunction()->getParent();
+ if (const auto *GV = M->getNamedValue(Name)) {
+ Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
+ break;
+ }
+ return error(Twine("use of undefined global value '@") + Name + "'");
+ }
+ case MIToken::GlobalValue: {
+ unsigned GVIdx;
+ if (getUnsigned(GVIdx))
+ return true;
+ if (GVIdx >= IRSlots.GlobalValues.size())
+ return error(Twine("use of undefined global value '@") + Twine(GVIdx) +
+ "'");
+ Dest = MachineOperand::CreateGA(IRSlots.GlobalValues[GVIdx],
+ /*Offset=*/0);
+ break;
+ }
+ default:
+ llvm_unreachable("The current token should be a global value");
+ }
+ // TODO: Parse offset and target flags.
+ lex();
+ return false;
+}
+
+bool MIParser::parseMachineOperand(MachineOperand &Dest) {
+ switch (Token.kind()) {
+ case MIToken::underscore:
+ case MIToken::NamedRegister:
+ return parseRegisterOperand(Dest);
+ case MIToken::IntegerLiteral:
+ return parseImmediateOperand(Dest);
+ case MIToken::MachineBasicBlock:
+ return parseMBBOperand(Dest);
+ case MIToken::GlobalValue:
+ case MIToken::NamedGlobalValue:
+ return parseGlobalAddressOperand(Dest);
+ case MIToken::Error:
+ return true;
+ case MIToken::Identifier:
+ if (const auto *RegMask = getRegMask(Token.stringValue())) {
+ Dest = MachineOperand::CreateRegMask(RegMask);
+ lex();
+ break;
+ }
+ // fallthrough
+ default:
+ // TODO: parse the other machine operands.
+ return error("expected a machine operand");
+ }
+ return false;
+}
+
+void MIParser::initNames2InstrOpCodes() {
+ if (!Names2InstrOpCodes.empty())
+ return;
+ const auto *TII = MF.getSubtarget().getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
+ Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
+}
+
+bool MIParser::parseInstrName(StringRef InstrName, unsigned &OpCode) {
+ initNames2InstrOpCodes();
+ auto InstrInfo = Names2InstrOpCodes.find(InstrName);
+ if (InstrInfo == Names2InstrOpCodes.end())
+ return true;
+ OpCode = InstrInfo->getValue();
+ return false;
+}
+
+void MIParser::initNames2Regs() {
+ if (!Names2Regs.empty())
+ return;
+ // The '%noreg' register is the register 0.
+ Names2Regs.insert(std::make_pair("noreg", 0));
+ const auto *TRI = MF.getSubtarget().getRegisterInfo();
+ assert(TRI && "Expected target register info");
+ for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
+ bool WasInserted =
+ Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
+ .second;
+ (void)WasInserted;
+ assert(WasInserted && "Expected registers to be unique case-insensitively");
+ }
+}
+
+bool MIParser::getRegisterByName(StringRef RegName, unsigned &Reg) {
+ initNames2Regs();
+ auto RegInfo = Names2Regs.find(RegName);
+ if (RegInfo == Names2Regs.end())
+ return true;
+ Reg = RegInfo->getValue();
+ return false;
+}
+
+void MIParser::initNames2RegMasks() {
+ if (!Names2RegMasks.empty())
+ return;
+ const auto *TRI = MF.getSubtarget().getRegisterInfo();
+ assert(TRI && "Expected target register info");
+ ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
+ ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
+ assert(RegMasks.size() == RegMaskNames.size());
+ for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
+ Names2RegMasks.insert(
+ std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
+}
+
+const uint32_t *MIParser::getRegMask(StringRef Identifier) {
+ initNames2RegMasks();
+ auto RegMaskInfo = Names2RegMasks.find(Identifier);
+ if (RegMaskInfo == Names2RegMasks.end())
+ return nullptr;
+ return RegMaskInfo->getValue();
+}
+
+bool llvm::parseMachineInstr(
+ MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF, StringRef Src,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots, SMDiagnostic &Error) {
+ return MIParser(SM, MF, Error, Src, MBBSlots, IRSlots).parse(MI);
+}
+
+bool llvm::parseMBBReference(
+ MachineBasicBlock *&MBB, SourceMgr &SM, MachineFunction &MF, StringRef Src,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots, SMDiagnostic &Error) {
+ return MIParser(SM, MF, Error, Src, MBBSlots, IRSlots).parseMBB(MBB);
+}
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
new file mode 100644
index 0000000..4d6d4e7
--- /dev/null
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIParser.h
@@ -0,0 +1,41 @@
+//===- MIParser.h - Machine Instructions Parser ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the function that parses the machine instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
+#define LLVM_LIB_CODEGEN_MIRPARSER_MIPARSER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineInstr;
+class MachineFunction;
+struct SlotMapping;
+class SMDiagnostic;
+class SourceMgr;
+
+bool parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF,
+ StringRef Src,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots, SMDiagnostic &Error);
+
+bool parseMBBReference(MachineBasicBlock *&MBB, SourceMgr &SM,
+ MachineFunction &MF, StringRef Src,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+ const SlotMapping &IRSlots, SMDiagnostic &Error);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 1fef3f6..3974583 100644
--- a/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -13,11 +13,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MIRParser/MIRParser.h"
+#include "MIParser.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/AsmParser/Parser.h"
+#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DiagnosticInfo.h"
@@ -43,6 +47,7 @@ class MIRParserImpl {
StringRef Filename;
LLVMContext &Context;
StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
+ SlotMapping IRSlots;
public:
MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
@@ -55,6 +60,12 @@ public:
/// Always returns true.
bool error(const Twine &Message);
+ /// Report a given error with the location translated from the location in an
+ /// embedded string literal to a location in the MIR file.
+ ///
+ /// Always returns true.
+ bool error(const SMDiagnostic &Error, SMRange SourceRange);
+
/// Try to parse the optional LLVM module and the machine functions in the MIR
/// file.
///
@@ -79,10 +90,19 @@ public:
/// Initialize the machine basic block using it's YAML representation.
///
/// Return true if an error occurred.
- bool initializeMachineBasicBlock(MachineBasicBlock &MBB,
- const yaml::MachineBasicBlock &YamlMBB);
+ bool initializeMachineBasicBlock(
+ MachineFunction &MF, MachineBasicBlock &MBB,
+ const yaml::MachineBasicBlock &YamlMBB,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
+
+ bool initializeRegisterInfo(MachineRegisterInfo &RegInfo,
+ const yaml::MachineFunction &YamlMF);
private:
+ /// Return a MIR diagnostic converted from an MI string diagnostic.
+ SMDiagnostic diagFromMIStringDiag(const SMDiagnostic &Error,
+ SMRange SourceRange);
+
/// Return a MIR diagnostic converted from an LLVM assembly diagnostic.
SMDiagnostic diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
SMRange SourceRange);
@@ -105,6 +125,12 @@ bool MIRParserImpl::error(const Twine &Message) {
return true;
}
+bool MIRParserImpl::error(const SMDiagnostic &Error, SMRange SourceRange) {
+ assert(Error.getKind() == SourceMgr::DK_Error && "Expected an error");
+ reportDiagnostic(diagFromMIStringDiag(Error, SourceRange));
+ return true;
+}
+
void MIRParserImpl::reportDiagnostic(const SMDiagnostic &Diag) {
DiagnosticSeverity Kind;
switch (Diag.getKind()) {
@@ -128,6 +154,7 @@ static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
std::unique_ptr<Module> MIRParserImpl::parse() {
yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
/*Ctxt=*/nullptr, handleYAMLDiag, this);
+ In.setContext(&In);
if (!In.setCurrentDocument()) {
if (In.error())
@@ -144,7 +171,7 @@ std::unique_ptr<Module> MIRParserImpl::parse() {
dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
SMDiagnostic Error;
M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
- Context);
+ Context, &IRSlots);
if (!M) {
reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()));
return M;
@@ -206,7 +233,11 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
MF.setAlignment(YamlMF.Alignment);
MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
MF.setHasInlineAsm(YamlMF.HasInlineAsm);
+ if (initializeRegisterInfo(MF.getRegInfo(), YamlMF))
+ return true;
+
const auto &F = *MF.getFunction();
+ DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
for (const auto &YamlMBB : YamlMF.BasicBlocks) {
const BasicBlock *BB = nullptr;
if (!YamlMBB.Name.empty()) {
@@ -218,21 +249,79 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
}
auto *MBB = MF.CreateMachineBasicBlock(BB);
MF.insert(MF.end(), MBB);
- if (initializeMachineBasicBlock(*MBB, YamlMBB))
+ bool WasInserted = MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
+ if (!WasInserted)
+ return error(Twine("redefinition of machine basic block with id #") +
+ Twine(YamlMBB.ID));
+ }
+
+ // Initialize the machine basic blocks after creating them all so that the
+ // machine instructions parser can resolve the MBB references.
+ unsigned I = 0;
+ for (const auto &YamlMBB : YamlMF.BasicBlocks) {
+ if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
+ MBBSlots))
return true;
}
return false;
}
bool MIRParserImpl::initializeMachineBasicBlock(
- MachineBasicBlock &MBB, const yaml::MachineBasicBlock &YamlMBB) {
+ MachineFunction &MF, MachineBasicBlock &MBB,
+ const yaml::MachineBasicBlock &YamlMBB,
+ const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
MBB.setAlignment(YamlMBB.Alignment);
if (YamlMBB.AddressTaken)
MBB.setHasAddressTaken();
MBB.setIsLandingPad(YamlMBB.IsLandingPad);
+ SMDiagnostic Error;
+ // Parse the successors.
+ for (const auto &MBBSource : YamlMBB.Successors) {
+ MachineBasicBlock *SuccMBB = nullptr;
+ if (parseMBBReference(SuccMBB, SM, MF, MBBSource.Value, MBBSlots, IRSlots,
+ Error))
+ return error(Error, MBBSource.SourceRange);
+ // TODO: Report an error when adding the same successor more than once.
+ MBB.addSuccessor(SuccMBB);
+ }
+ // Parse the instructions.
+ for (const auto &MISource : YamlMBB.Instructions) {
+ MachineInstr *MI = nullptr;
+ if (parseMachineInstr(MI, SM, MF, MISource.Value, MBBSlots, IRSlots, Error))
+ return error(Error, MISource.SourceRange);
+ MBB.insert(MBB.end(), MI);
+ }
return false;
}
+bool MIRParserImpl::initializeRegisterInfo(
+ MachineRegisterInfo &RegInfo, const yaml::MachineFunction &YamlMF) {
+ assert(RegInfo.isSSA());
+ if (!YamlMF.IsSSA)
+ RegInfo.leaveSSA();
+ assert(RegInfo.tracksLiveness());
+ if (!YamlMF.TracksRegLiveness)
+ RegInfo.invalidateLiveness();
+ RegInfo.enableSubRegLiveness(YamlMF.TracksSubRegLiveness);
+ return false;
+}
+
+SMDiagnostic MIRParserImpl::diagFromMIStringDiag(const SMDiagnostic &Error,
+ SMRange SourceRange) {
+ assert(SourceRange.isValid() && "Invalid source range");
+ SMLoc Loc = SourceRange.Start;
+ bool HasQuote = Loc.getPointer() < SourceRange.End.getPointer() &&
+ *Loc.getPointer() == '\'';
+ // Translate the location of the error from the location in the MI string to
+ // the corresponding location in the MIR file.
+ Loc = Loc.getFromPointer(Loc.getPointer() + Error.getColumnNo() +
+ (HasQuote ? 1 : 0));
+
+ // TODO: Translate any source ranges as well.
+ return SM.GetMessage(Loc, Error.getKind(), Error.getMessage(), None,
+ Error.getFixIts());
+}
+
SMDiagnostic MIRParserImpl::diagFromLLVMAssemblyDiag(const SMDiagnostic &Error,
SMRange SourceRange) {
assert(SourceRange.isValid());
diff --git a/contrib/llvm/lib/CodeGen/MIRPrinter.cpp b/contrib/llvm/lib/CodeGen/MIRPrinter.cpp
index bbf163a..76cbe29 100644
--- a/contrib/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -15,12 +15,15 @@
#include "MIRPrinter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
@@ -30,13 +33,36 @@ namespace {
/// format.
class MIRPrinter {
raw_ostream &OS;
+ DenseMap<const uint32_t *, unsigned> RegisterMaskIds;
public:
MIRPrinter(raw_ostream &OS) : OS(OS) {}
void print(const MachineFunction &MF);
- void convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB);
+ void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo);
+ void convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
+ const MachineBasicBlock &MBB);
+
+private:
+ void initRegisterMaskIds(const MachineFunction &MF);
+};
+
+/// This class prints out the machine instructions using the MIR serialization
+/// format.
+class MIPrinter {
+ const Module &M;
+ raw_ostream &OS;
+ const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds;
+
+public:
+ MIPrinter(const Module &M, raw_ostream &OS,
+ const DenseMap<const uint32_t *, unsigned> &RegisterMaskIds)
+ : M(M), OS(OS), RegisterMaskIds(RegisterMaskIds) {}
+
+ void print(const MachineInstr &MI);
+ void printMBBReference(const MachineBasicBlock &MBB);
+ void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
};
} // end anonymous namespace
@@ -59,22 +85,44 @@ template <> struct BlockScalarTraits<Module> {
} // end namespace llvm
void MIRPrinter::print(const MachineFunction &MF) {
+ initRegisterMaskIds(MF);
+
yaml::MachineFunction YamlMF;
YamlMF.Name = MF.getName();
YamlMF.Alignment = MF.getAlignment();
YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
YamlMF.HasInlineAsm = MF.hasInlineAsm();
+ convert(YamlMF, MF.getRegInfo());
+
+ int I = 0;
+ const auto &M = *MF.getFunction()->getParent();
for (const auto &MBB : MF) {
+ // TODO: Allow printing of non sequentially numbered MBBs.
+ // This is currently needed as the basic block references get their index
+ // from MBB.getNumber(), thus it should be sequential so that the parser can
+ // map back to the correct MBBs when parsing the output.
+ assert(MBB.getNumber() == I++ &&
+ "Can't print MBBs that aren't sequentially numbered");
+ (void)I;
yaml::MachineBasicBlock YamlMBB;
- convert(YamlMBB, MBB);
+ convert(M, YamlMBB, MBB);
YamlMF.BasicBlocks.push_back(YamlMBB);
}
yaml::Output Out(OS);
Out << YamlMF;
}
-void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB,
+void MIRPrinter::convert(yaml::MachineFunction &MF,
+ const MachineRegisterInfo &RegInfo) {
+ MF.IsSSA = RegInfo.isSSA();
+ MF.TracksRegLiveness = RegInfo.tracksLiveness();
+ MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
+}
+
+void MIRPrinter::convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
const MachineBasicBlock &MBB) {
+ assert(MBB.getNumber() >= 0 && "Invalid MBB number");
+ YamlMBB.ID = (unsigned)MBB.getNumber();
// TODO: Serialize unnamed BB references.
if (const auto *BB = MBB.getBasicBlock())
YamlMBB.Name = BB->hasName() ? BB->getName() : "<unnamed bb>";
@@ -83,6 +131,115 @@ void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB,
YamlMBB.Alignment = MBB.getAlignment();
YamlMBB.AddressTaken = MBB.hasAddressTaken();
YamlMBB.IsLandingPad = MBB.isLandingPad();
+ for (const auto *SuccMBB : MBB.successors()) {
+ std::string Str;
+ raw_string_ostream StrOS(Str);
+ MIPrinter(M, StrOS, RegisterMaskIds).printMBBReference(*SuccMBB);
+ YamlMBB.Successors.push_back(StrOS.str());
+ }
+
+ // Print the machine instructions.
+ YamlMBB.Instructions.reserve(MBB.size());
+ std::string Str;
+ for (const auto &MI : MBB) {
+ raw_string_ostream StrOS(Str);
+ MIPrinter(M, StrOS, RegisterMaskIds).print(MI);
+ YamlMBB.Instructions.push_back(StrOS.str());
+ Str.clear();
+ }
+}
+
+void MIRPrinter::initRegisterMaskIds(const MachineFunction &MF) {
+ const auto *TRI = MF.getSubtarget().getRegisterInfo();
+ unsigned I = 0;
+ for (const uint32_t *Mask : TRI->getRegMasks())
+ RegisterMaskIds.insert(std::make_pair(Mask, I++));
+}
+
+void MIPrinter::print(const MachineInstr &MI) {
+ const auto &SubTarget = MI.getParent()->getParent()->getSubtarget();
+ const auto *TRI = SubTarget.getRegisterInfo();
+ assert(TRI && "Expected target register info");
+ const auto *TII = SubTarget.getInstrInfo();
+ assert(TII && "Expected target instruction info");
+
+ unsigned I = 0, E = MI.getNumOperands();
+ for (; I < E && MI.getOperand(I).isReg() && MI.getOperand(I).isDef() &&
+ !MI.getOperand(I).isImplicit();
+ ++I) {
+ if (I)
+ OS << ", ";
+ print(MI.getOperand(I), TRI);
+ }
+
+ if (I)
+ OS << " = ";
+ OS << TII->getName(MI.getOpcode());
+ // TODO: Print the instruction flags, machine mem operands.
+ if (I < E)
+ OS << ' ';
+
+ bool NeedComma = false;
+ for (; I < E; ++I) {
+ if (NeedComma)
+ OS << ", ";
+ print(MI.getOperand(I), TRI);
+ NeedComma = true;
+ }
+}
+
+static void printReg(unsigned Reg, raw_ostream &OS,
+ const TargetRegisterInfo *TRI) {
+ // TODO: Print Stack Slots.
+ // TODO: Print virtual registers.
+ if (!Reg)
+ OS << '_';
+ else if (Reg < TRI->getNumRegs())
+ OS << '%' << StringRef(TRI->getName(Reg)).lower();
+ else
+ llvm_unreachable("Can't print this kind of register yet");
+}
+
+void MIPrinter::printMBBReference(const MachineBasicBlock &MBB) {
+ OS << "%bb." << MBB.getNumber();
+ if (const auto *BB = MBB.getBasicBlock()) {
+ if (BB->hasName())
+ OS << '.' << BB->getName();
+ }
+}
+
+void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
+ switch (Op.getType()) {
+ case MachineOperand::MO_Register:
+ // TODO: Print register flags.
+ printReg(Op.getReg(), OS, TRI);
+ // TODO: Print sub register.
+ break;
+ case MachineOperand::MO_Immediate:
+ OS << Op.getImm();
+ break;
+ case MachineOperand::MO_MachineBasicBlock:
+ printMBBReference(*Op.getMBB());
+ break;
+ case MachineOperand::MO_GlobalAddress:
+ // FIXME: Make this faster - print as operand will create a slot tracker to
+ // print unnamed values for the whole module every time it's called, which
+ // is inefficient.
+ Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, &M);
+ // TODO: Print offset and target flags.
+ break;
+ case MachineOperand::MO_RegisterMask: {
+ auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
+ if (RegMaskInfo != RegisterMaskIds.end())
+ OS << StringRef(TRI->getRegMaskNames()[RegMaskInfo->second]).lower();
+ else
+ llvm_unreachable("Can't print this machine register mask yet.");
+ break;
+ }
+ default:
+ // TODO: Print the other machine operands.
+ llvm_unreachable("Can't print this machine operand at the moment");
+ }
}
void llvm::printMIR(raw_ostream &OS, const Module &M) {
diff --git a/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp b/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp
index d5fdf8e..5d3f7eb 100644
--- a/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -24,6 +24,7 @@
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/Debug.h"
@@ -171,9 +172,8 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
return I;
}
-MachineBasicBlock::const_iterator
-MachineBasicBlock::getFirstTerminator() const {
- const_iterator B = begin(), E = end(), I = E;
+MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() {
+ instr_iterator B = instr_begin(), E = instr_end(), I = E;
while (I != B && ((--I)->isTerminator() || I->isDebugValue()))
; /*noop */
while (I != E && !I->isTerminator())
@@ -181,11 +181,10 @@ MachineBasicBlock::getFirstTerminator() const {
return I;
}
-MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() {
- instr_iterator B = instr_begin(), E = instr_end(), I = E;
- while (I != B && ((--I)->isTerminator() || I->isDebugValue()))
- ; /*noop */
- while (I != E && !I->isTerminator())
+MachineBasicBlock::iterator MachineBasicBlock::getFirstNonDebugInstr() {
+ // Skip over begin-of-block dbg_value instructions.
+ iterator I = begin(), E = end();
+ while (I != E && I->isDebugValue())
++I;
return I;
}
@@ -204,21 +203,6 @@ MachineBasicBlock::iterator MachineBasicBlock::getLastNonDebugInstr() {
return end();
}
-MachineBasicBlock::const_iterator
-MachineBasicBlock::getLastNonDebugInstr() const {
- // Skip over end-of-block dbg_value instructions.
- const_instr_iterator B = instr_begin(), I = instr_end();
- while (I != B) {
- --I;
- // Return instruction that starts a bundle.
- if (I->isDebugValue() || I->isInsideBundle())
- continue;
- return I;
- }
- // The block is all debug values.
- return end();
-}
-
const MachineBasicBlock *MachineBasicBlock::getLandingPadSuccessor() const {
// A block with a landing pad successor only has one other successor.
if (succ_size() > 2)
@@ -261,6 +245,20 @@ void MachineBasicBlock::print(raw_ostream &OS, SlotIndexes *Indexes) const {
<< " is null\n";
return;
}
+ const Function *F = MF->getFunction();
+ const Module *M = F ? F->getParent() : nullptr;
+ ModuleSlotTracker MST(M);
+ print(OS, MST, Indexes);
+}
+
+void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
+ SlotIndexes *Indexes) const {
+ const MachineFunction *MF = getParent();
+ if (!MF) {
+ OS << "Can't print out MachineBasicBlock because parent MachineFunction"
+ << " is null\n";
+ return;
+ }
if (Indexes)
OS << Indexes->getMBBStartIdx(this) << '\t';
@@ -270,7 +268,7 @@ void MachineBasicBlock::print(raw_ostream &OS, SlotIndexes *Indexes) const {
const char *Comma = "";
if (const BasicBlock *LBB = getBasicBlock()) {
OS << Comma << "derived from LLVM BB ";
- LBB->printAsOperand(OS, /*PrintType=*/false);
+ LBB->printAsOperand(OS, /*PrintType=*/false, MST);
Comma = ", ";
}
if (isLandingPad()) { OS << Comma << "EH LANDING PAD"; Comma = ", "; }
@@ -307,7 +305,7 @@ void MachineBasicBlock::print(raw_ostream &OS, SlotIndexes *Indexes) const {
OS << '\t';
if (I->isInsideBundle())
OS << " * ";
- I->print(OS);
+ I->print(OS, MST);
}
// Print the successors of this block according to the CFG.
diff --git a/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index 141990b..2969bad 100644
--- a/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -179,7 +179,7 @@ public:
/// in-loop predecessors of this chain.
unsigned LoopPredecessors;
};
-} // namespace
+}
namespace {
class MachineBlockPlacement : public MachineFunctionPass {
@@ -267,7 +267,7 @@ public:
MachineFunctionPass::getAnalysisUsage(AU);
}
};
-} // namespace
+}
char MachineBlockPlacement::ID = 0;
char &llvm::MachineBlockPlacementID = MachineBlockPlacement::ID;
@@ -1185,7 +1185,7 @@ public:
MachineFunctionPass::getAnalysisUsage(AU);
}
};
-} // namespace
+}
char MachineBlockPlacementStats::ID = 0;
char &llvm::MachineBlockPlacementStatsID = MachineBlockPlacementStats::ID;
diff --git a/contrib/llvm/lib/CodeGen/MachineCombiner.cpp b/contrib/llvm/lib/CodeGen/MachineCombiner.cpp
index 5019e8e..f33d0e6 100644
--- a/contrib/llvm/lib/CodeGen/MachineCombiner.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineCombiner.cpp
@@ -67,10 +67,11 @@ private:
unsigned getLatency(MachineInstr *Root, MachineInstr *NewRoot,
MachineTraceMetrics::Trace BlockTrace);
bool
- preservesCriticalPathLen(MachineBasicBlock *MBB, MachineInstr *Root,
+ improvesCriticalPathLen(MachineBasicBlock *MBB, MachineInstr *Root,
MachineTraceMetrics::Trace BlockTrace,
SmallVectorImpl<MachineInstr *> &InsInstrs,
- DenseMap<unsigned, unsigned> &InstrIdxForVirtReg);
+ DenseMap<unsigned, unsigned> &InstrIdxForVirtReg,
+ bool NewCodeHasLessInsts);
bool preservesResourceLen(MachineBasicBlock *MBB,
MachineTraceMetrics::Trace BlockTrace,
SmallVectorImpl<MachineInstr *> &InsInstrs,
@@ -78,7 +79,7 @@ private:
void instr2instrSC(SmallVectorImpl<MachineInstr *> &Instrs,
SmallVectorImpl<const MCSchedClassDesc *> &InstrsSC);
};
-} // namespace
+}
char MachineCombiner::ID = 0;
char &llvm::MachineCombinerID = MachineCombiner::ID;
@@ -208,19 +209,24 @@ unsigned MachineCombiner::getLatency(MachineInstr *Root, MachineInstr *NewRoot,
return NewRootLatency;
}
-/// True when the new instruction sequence does not
-/// lengthen the critical path. The DAGCombine code sequence ends in MI
-/// (Machine Instruction) Root. The new code sequence ends in MI NewRoot. A
-/// necessary condition for the new sequence to replace the old sequence is that
-/// it cannot lengthen the critical path. This is decided by the formula
+/// True when the new instruction sequence does not lengthen the critical path
+/// and the new sequence has less instructions or the new sequence improves the
+/// critical path.
+/// The DAGCombine code sequence ends in MI (Machine Instruction) Root.
+/// The new code sequence ends in MI NewRoot. A necessary condition for the new
+/// sequence to replace the old sequence is that it cannot lengthen the critical
+/// path. This is decided by the formula:
/// (NewRootDepth + NewRootLatency) <= (RootDepth + RootLatency + RootSlack)).
-/// The slack is the number of cycles Root can be delayed before the critical
-/// patch becomes longer.
-bool MachineCombiner::preservesCriticalPathLen(
+/// If the new sequence has an equal length critical path but does not reduce
+/// the number of instructions (NewCodeHasLessInsts is false), then it is not
+/// considered an improvement. The slack is the number of cycles Root can be
+/// delayed before the critical patch becomes longer.
+bool MachineCombiner::improvesCriticalPathLen(
MachineBasicBlock *MBB, MachineInstr *Root,
MachineTraceMetrics::Trace BlockTrace,
SmallVectorImpl<MachineInstr *> &InsInstrs,
- DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) {
+ DenseMap<unsigned, unsigned> &InstrIdxForVirtReg,
+ bool NewCodeHasLessInsts) {
assert(TSchedModel.hasInstrSchedModel() && "Missing machine model\n");
// NewRoot is the last instruction in the \p InsInstrs vector.
@@ -245,9 +251,13 @@ bool MachineCombiner::preservesCriticalPathLen(
dbgs() << " RootDepth + RootLatency + RootSlack "
<< RootDepth + RootLatency + RootSlack << "\n";);
- /// True when the new sequence does not lengthen the critical path.
- return ((NewRootDepth + NewRootLatency) <=
- (RootDepth + RootLatency + RootSlack));
+ unsigned NewCycleCount = NewRootDepth + NewRootLatency;
+ unsigned OldCycleCount = RootDepth + RootLatency + RootSlack;
+
+ if (NewCodeHasLessInsts)
+ return NewCycleCount <= OldCycleCount;
+ else
+ return NewCycleCount < OldCycleCount;
}
/// helper routine to convert instructions into SC
@@ -359,18 +369,21 @@ bool MachineCombiner::combineInstructions(MachineBasicBlock *MBB) {
Traces->verifyAnalysis();
TII->genAlternativeCodeSequence(MI, P, InsInstrs, DelInstrs,
InstrIdxForVirtReg);
+ unsigned NewInstCount = InsInstrs.size();
+ unsigned OldInstCount = DelInstrs.size();
// Found pattern, but did not generate alternative sequence.
// This can happen e.g. when an immediate could not be materialized
// in a single instruction.
- if (!InsInstrs.size())
+ if (!NewInstCount)
continue;
// Substitute when we optimize for codesize and the new sequence has
// fewer instructions OR
// the new sequence neither lengthens the critical path nor increases
// resource pressure.
- if (doSubstitute(InsInstrs.size(), DelInstrs.size()) ||
- (preservesCriticalPathLen(MBB, &MI, BlockTrace, InsInstrs,
- InstrIdxForVirtReg) &&
+ if (doSubstitute(NewInstCount, OldInstCount) ||
+ (improvesCriticalPathLen(MBB, &MI, BlockTrace, InsInstrs,
+ InstrIdxForVirtReg,
+ NewInstCount < OldInstCount) &&
preservesResourceLen(MBB, BlockTrace, InsInstrs, DelInstrs))) {
for (auto *InstrPtr : InsInstrs)
MBB->insert((MachineBasicBlock::iterator) &MI, InstrPtr);
diff --git a/contrib/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/contrib/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index ec171b0..a686341 100644
--- a/contrib/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -55,7 +55,7 @@ namespace {
DenseMap<unsigned, MachineInstr*> &AvailCopyMap);
bool CopyPropagateBlock(MachineBasicBlock &MBB);
};
-} // namespace
+}
char MachineCopyPropagation::ID = 0;
char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
diff --git a/contrib/llvm/lib/CodeGen/MachineFunction.cpp b/contrib/llvm/lib/CodeGen/MachineFunction.cpp
index 67b9d77..800d1b5 100644
--- a/contrib/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineFunction.cpp
@@ -29,6 +29,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/Debug.h"
@@ -361,9 +362,11 @@ void MachineFunction::print(raw_ostream &OS, SlotIndexes *Indexes) const {
OS << '\n';
}
+ ModuleSlotTracker MST(getFunction()->getParent());
+ MST.incorporateFunction(*getFunction());
for (const auto &BB : *this) {
OS << '\n';
- BB.print(OS, Indexes);
+ BB.print(OS, MST, Indexes);
}
OS << "\n# End machine code for function " << getName() << ".\n\n";
@@ -404,7 +407,7 @@ namespace llvm {
return OutStr;
}
};
-} // namespace llvm
+}
void MachineFunction::viewCFG() const
{
diff --git a/contrib/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp b/contrib/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp
index 57b7230..790f5ac 100644
--- a/contrib/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp
@@ -49,7 +49,7 @@ struct MachineFunctionPrinterPass : public MachineFunctionPass {
};
char MachineFunctionPrinterPass::ID = 0;
-} // namespace
+}
char &llvm::MachineFunctionPrinterPassID = MachineFunctionPrinterPass::ID;
INITIALIZE_PASS(MachineFunctionPrinterPass, "machineinstr-printer",
diff --git a/contrib/llvm/lib/CodeGen/MachineInstr.cpp b/contrib/llvm/lib/CodeGen/MachineInstr.cpp
index 19ba5cf..fdc4226 100644
--- a/contrib/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineInstr.cpp
@@ -28,6 +28,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCInstrDesc.h"
@@ -296,10 +297,14 @@ hash_code llvm::hash_value(const MachineOperand &MO) {
llvm_unreachable("Invalid machine operand type");
}
-/// print - Print the specified machine operand.
-///
void MachineOperand::print(raw_ostream &OS,
const TargetRegisterInfo *TRI) const {
+ ModuleSlotTracker DummyMST(nullptr);
+ print(OS, DummyMST, TRI);
+}
+
+void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
+ const TargetRegisterInfo *TRI) const {
switch (getType()) {
case MachineOperand::MO_Register:
OS << PrintReg(getReg(), TRI, getSubReg());
@@ -387,7 +392,7 @@ void MachineOperand::print(raw_ostream &OS,
break;
case MachineOperand::MO_GlobalAddress:
OS << "<ga:";
- getGlobal()->printAsOperand(OS, /*PrintType=*/false);
+ getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
if (getOffset()) OS << "+" << getOffset();
OS << '>';
break;
@@ -398,7 +403,7 @@ void MachineOperand::print(raw_ostream &OS,
break;
case MachineOperand::MO_BlockAddress:
OS << '<';
- getBlockAddress()->printAsOperand(OS, /*PrintType=*/false);
+ getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST);
if (getOffset()) OS << "+" << getOffset();
OS << '>';
break;
@@ -410,7 +415,7 @@ void MachineOperand::print(raw_ostream &OS,
break;
case MachineOperand::MO_Metadata:
OS << '<';
- getMetadata()->printAsOperand(OS);
+ getMetadata()->printAsOperand(OS, MST);
OS << '>';
break;
case MachineOperand::MO_MCSymbol:
@@ -505,63 +510,66 @@ uint64_t MachineMemOperand::getAlignment() const {
return MinAlign(getBaseAlignment(), getOffset());
}
-raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
- assert((MMO.isLoad() || MMO.isStore()) &&
+void MachineMemOperand::print(raw_ostream &OS) const {
+ ModuleSlotTracker DummyMST(nullptr);
+ print(OS, DummyMST);
+}
+void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {
+ assert((isLoad() || isStore()) &&
"SV has to be a load, store or both.");
- if (MMO.isVolatile())
+ if (isVolatile())
OS << "Volatile ";
- if (MMO.isLoad())
+ if (isLoad())
OS << "LD";
- if (MMO.isStore())
+ if (isStore())
OS << "ST";
- OS << MMO.getSize();
+ OS << getSize();
// Print the address information.
OS << "[";
- if (const Value *V = MMO.getValue())
- V->printAsOperand(OS, /*PrintType=*/false);
- else if (const PseudoSourceValue *PSV = MMO.getPseudoValue())
+ if (const Value *V = getValue())
+ V->printAsOperand(OS, /*PrintType=*/false, MST);
+ else if (const PseudoSourceValue *PSV = getPseudoValue())
PSV->printCustom(OS);
else
OS << "<unknown>";
- unsigned AS = MMO.getAddrSpace();
+ unsigned AS = getAddrSpace();
if (AS != 0)
OS << "(addrspace=" << AS << ')';
// If the alignment of the memory reference itself differs from the alignment
// of the base pointer, print the base alignment explicitly, next to the base
// pointer.
- if (MMO.getBaseAlignment() != MMO.getAlignment())
- OS << "(align=" << MMO.getBaseAlignment() << ")";
+ if (getBaseAlignment() != getAlignment())
+ OS << "(align=" << getBaseAlignment() << ")";
- if (MMO.getOffset() != 0)
- OS << "+" << MMO.getOffset();
+ if (getOffset() != 0)
+ OS << "+" << getOffset();
OS << "]";
// Print the alignment of the reference.
- if (MMO.getBaseAlignment() != MMO.getAlignment() ||
- MMO.getBaseAlignment() != MMO.getSize())
- OS << "(align=" << MMO.getAlignment() << ")";
+ if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize())
+ OS << "(align=" << getAlignment() << ")";
// Print TBAA info.
- if (const MDNode *TBAAInfo = MMO.getAAInfo().TBAA) {
+ if (const MDNode *TBAAInfo = getAAInfo().TBAA) {
OS << "(tbaa=";
if (TBAAInfo->getNumOperands() > 0)
- TBAAInfo->getOperand(0)->printAsOperand(OS);
+ TBAAInfo->getOperand(0)->printAsOperand(OS, MST);
else
OS << "<unknown>";
OS << ")";
}
// Print AA scope info.
- if (const MDNode *ScopeInfo = MMO.getAAInfo().Scope) {
+ if (const MDNode *ScopeInfo = getAAInfo().Scope) {
OS << "(alias.scope=";
if (ScopeInfo->getNumOperands() > 0)
for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) {
- ScopeInfo->getOperand(i)->printAsOperand(OS);
+ ScopeInfo->getOperand(i)->printAsOperand(OS, MST);
if (i != ie-1)
OS << ",";
}
@@ -571,11 +579,11 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
}
// Print AA noalias scope info.
- if (const MDNode *NoAliasInfo = MMO.getAAInfo().NoAlias) {
+ if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) {
OS << "(noalias=";
if (NoAliasInfo->getNumOperands() > 0)
for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) {
- NoAliasInfo->getOperand(i)->printAsOperand(OS);
+ NoAliasInfo->getOperand(i)->printAsOperand(OS, MST);
if (i != ie-1)
OS << ",";
}
@@ -585,10 +593,11 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
}
// Print nontemporal info.
- if (MMO.isNonTemporal())
+ if (isNonTemporal())
OS << "(nontemporal)";
- return OS;
+ if (isInvariant())
+ OS << "(invariant)";
}
//===----------------------------------------------------------------------===//
@@ -1523,6 +1532,17 @@ void MachineInstr::dump() const {
}
void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
+ const Module *M = nullptr;
+ if (const MachineBasicBlock *MBB = getParent())
+ if (const MachineFunction *MF = MBB->getParent())
+ M = MF->getFunction()->getParent();
+
+ ModuleSlotTracker MST(M);
+ print(OS, MST, SkipOpers);
+}
+
+void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
+ bool SkipOpers) const {
// We can be a bit tidier if we know the MachineFunction.
const MachineFunction *MF = nullptr;
const TargetRegisterInfo *TRI = nullptr;
@@ -1547,7 +1567,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
!getOperand(StartOp).isImplicit();
++StartOp) {
if (StartOp != 0) OS << ", ";
- getOperand(StartOp).print(OS, TRI);
+ getOperand(StartOp).print(OS, MST, TRI);
unsigned Reg = getOperand(StartOp).getReg();
if (TargetRegisterInfo::isVirtualRegister(Reg))
VirtRegs.push_back(Reg);
@@ -1574,7 +1594,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
// Print asm string.
OS << " ";
- getOperand(InlineAsm::MIOp_AsmString).print(OS, TRI);
+ getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI);
// Print HasSideEffects, MayLoad, MayStore, IsAlignStack
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
@@ -1642,7 +1662,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
if (DIV && !DIV->getName().empty())
OS << "!\"" << DIV->getName() << '\"';
else
- MO.print(OS, TRI);
+ MO.print(OS, MST, TRI);
} else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) {
OS << TRI->getSubRegIndexName(MO.getImm());
} else if (i == AsmDescOp && MO.isImm()) {
@@ -1676,7 +1696,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
// Compute the index of the next operand descriptor.
AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag);
} else
- MO.print(OS, TRI);
+ MO.print(OS, MST, TRI);
}
// Briefly indicate whether any call clobbers were omitted.
@@ -1701,7 +1721,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
OS << " mem:";
for (mmo_iterator i = memoperands_begin(), e = memoperands_end();
i != e; ++i) {
- OS << **i;
+ (*i)->print(OS, MST);
if (std::next(i) != e)
OS << " ";
}
diff --git a/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp b/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp
index a303426..42d0603 100644
--- a/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -54,9 +54,8 @@ public:
class MMIAddrLabelMap {
MCContext &Context;
struct AddrLabelSymEntry {
- /// Symbols - The symbols for the label. This is a pointer union that is
- /// either one symbol (the common case) or a list of symbols.
- PointerUnion<MCSymbol *, std::vector<MCSymbol*>*> Symbols;
+ /// Symbols - The symbols for the label.
+ TinyPtrVector<MCSymbol *> Symbols;
Function *Fn; // The containing function of the BasicBlock.
unsigned Index; // The index in BBCallbacks for the BasicBlock.
@@ -80,16 +79,9 @@ public:
~MMIAddrLabelMap() {
assert(DeletedAddrLabelsNeedingEmission.empty() &&
"Some labels for deleted blocks never got emitted");
-
- // Deallocate any of the 'list of symbols' case.
- for (DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry>::iterator
- I = AddrLabelSymbols.begin(), E = AddrLabelSymbols.end(); I != E; ++I)
- if (I->second.Symbols.is<std::vector<MCSymbol*>*>())
- delete I->second.Symbols.get<std::vector<MCSymbol*>*>();
}
- MCSymbol *getAddrLabelSymbol(BasicBlock *BB);
- std::vector<MCSymbol*> getAddrLabelSymbolToEmit(BasicBlock *BB);
+ ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
void takeDeletedSymbolsForFunction(Function *F,
std::vector<MCSymbol*> &Result);
@@ -97,51 +89,29 @@ public:
void UpdateForDeletedBlock(BasicBlock *BB);
void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
};
-} // namespace llvm
+}
-MCSymbol *MMIAddrLabelMap::getAddrLabelSymbol(BasicBlock *BB) {
+ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
assert(BB->hasAddressTaken() &&
"Shouldn't get label for block without address taken");
AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
// If we already had an entry for this block, just return it.
- if (!Entry.Symbols.isNull()) {
+ if (!Entry.Symbols.empty()) {
assert(BB->getParent() == Entry.Fn && "Parent changed");
- if (Entry.Symbols.is<MCSymbol*>())
- return Entry.Symbols.get<MCSymbol*>();
- return (*Entry.Symbols.get<std::vector<MCSymbol*>*>())[0];
+ return Entry.Symbols;
}
// Otherwise, this is a new entry, create a new symbol for it and add an
// entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
BBCallbacks.emplace_back(BB);
BBCallbacks.back().setMap(this);
- Entry.Index = BBCallbacks.size()-1;
+ Entry.Index = BBCallbacks.size() - 1;
Entry.Fn = BB->getParent();
- MCSymbol *Result = Context.createTempSymbol();
- Entry.Symbols = Result;
- return Result;
+ Entry.Symbols.push_back(Context.createTempSymbol());
+ return Entry.Symbols;
}
-std::vector<MCSymbol*>
-MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
- assert(BB->hasAddressTaken() &&
- "Shouldn't get label for block without address taken");
- AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
-
- std::vector<MCSymbol*> Result;
-
- // If we already had an entry for this block, just return it.
- if (Entry.Symbols.isNull())
- Result.push_back(getAddrLabelSymbol(BB));
- else if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>())
- Result.push_back(Sym);
- else
- Result = *Entry.Symbols.get<std::vector<MCSymbol*>*>();
- return Result;
-}
-
-
/// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
/// them.
void MMIAddrLabelMap::
@@ -162,16 +132,15 @@ void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
// If the block got deleted, there is no need for the symbol. If the symbol
// was already emitted, we can just forget about it, otherwise we need to
// queue it up for later emission when the function is output.
- AddrLabelSymEntry Entry = AddrLabelSymbols[BB];
+ AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
AddrLabelSymbols.erase(BB);
- assert(!Entry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
+ assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
BBCallbacks[Entry.Index] = nullptr; // Clear the callback.
assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
"Block/parent mismatch");
- // Handle both the single and the multiple symbols cases.
- if (MCSymbol *Sym = Entry.Symbols.dyn_cast<MCSymbol*>()) {
+ for (MCSymbol *Sym : Entry.Symbols) {
if (Sym->isDefined())
return;
@@ -180,64 +149,29 @@ void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
// for the containing Function. Since the block is being deleted, its
// parent may already be removed, we have to get the function from 'Entry'.
DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
- } else {
- std::vector<MCSymbol*> *Syms = Entry.Symbols.get<std::vector<MCSymbol*>*>();
-
- for (unsigned i = 0, e = Syms->size(); i != e; ++i) {
- MCSymbol *Sym = (*Syms)[i];
- if (Sym->isDefined()) continue; // Ignore already emitted labels.
-
- // If the block is not yet defined, we need to emit it at the end of the
- // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list
- // for the containing Function. Since the block is being deleted, its
- // parent may already be removed, we have to get the function from
- // 'Entry'.
- DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
- }
-
- // The entry is deleted, free the memory associated with the symbol list.
- delete Syms;
}
}
void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
// Get the entry for the RAUW'd block and remove it from our map.
- AddrLabelSymEntry OldEntry = AddrLabelSymbols[Old];
+ AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
AddrLabelSymbols.erase(Old);
- assert(!OldEntry.Symbols.isNull() && "Didn't have a symbol, why a callback?");
+ assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
// If New is not address taken, just move our symbol over to it.
- if (NewEntry.Symbols.isNull()) {
+ if (NewEntry.Symbols.empty()) {
BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.
- NewEntry = OldEntry; // Set New's entry.
+ NewEntry = std::move(OldEntry); // Set New's entry.
return;
}
BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.
- // Otherwise, we need to add the old symbol to the new block's set. If it is
- // just a single entry, upgrade it to a symbol list.
- if (MCSymbol *PrevSym = NewEntry.Symbols.dyn_cast<MCSymbol*>()) {
- std::vector<MCSymbol*> *SymList = new std::vector<MCSymbol*>();
- SymList->push_back(PrevSym);
- NewEntry.Symbols = SymList;
- }
-
- std::vector<MCSymbol*> *SymList =
- NewEntry.Symbols.get<std::vector<MCSymbol*>*>();
-
- // If the old entry was a single symbol, add it.
- if (MCSymbol *Sym = OldEntry.Symbols.dyn_cast<MCSymbol*>()) {
- SymList->push_back(Sym);
- return;
- }
-
- // Otherwise, concatenate the list.
- std::vector<MCSymbol*> *Syms =OldEntry.Symbols.get<std::vector<MCSymbol*>*>();
- SymList->insert(SymList->end(), Syms->begin(), Syms->end());
- delete Syms;
+ // Otherwise, we need to add the old symbols to the new block's set.
+ NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(),
+ OldEntry.Symbols.end());
}
@@ -273,8 +207,8 @@ bool MachineModuleInfo::doInitialization(Module &M) {
ObjFileMMI = nullptr;
CurCallSite = 0;
- CallsEHReturn = 0;
- CallsUnwindInit = 0;
+ CallsEHReturn = false;
+ CallsUnwindInit = false;
DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
// Always emit some info, by default "no personality" info.
Personalities.push_back(nullptr);
@@ -313,29 +247,18 @@ void MachineModuleInfo::EndFunction() {
TypeInfos.clear();
FilterIds.clear();
FilterEnds.clear();
- CallsEHReturn = 0;
- CallsUnwindInit = 0;
+ CallsEHReturn = false;
+ CallsUnwindInit = false;
VariableDbgInfos.clear();
}
//===- Address of Block Management ----------------------------------------===//
-
-/// getAddrLabelSymbol - Return the symbol to be used for the specified basic
-/// block when its address is taken. This cannot be its normal LBB label
-/// because the block may be accessed outside its containing function.
-MCSymbol *MachineModuleInfo::getAddrLabelSymbol(const BasicBlock *BB) {
- // Lazily create AddrLabelSymbols.
- if (!AddrLabelSymbols)
- AddrLabelSymbols = new MMIAddrLabelMap(Context);
- return AddrLabelSymbols->getAddrLabelSymbol(const_cast<BasicBlock*>(BB));
-}
-
/// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
/// basic block when its address is taken. If other blocks were RAUW'd to
/// this one, we may have to emit them as well, return the whole set.
-std::vector<MCSymbol*> MachineModuleInfo::
-getAddrLabelSymbolToEmit(const BasicBlock *BB) {
+ArrayRef<MCSymbol *>
+MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
// Lazily create AddrLabelSymbols.
if (!AddrLabelSymbols)
AddrLabelSymbols = new MMIAddrLabelMap(Context);
diff --git a/contrib/llvm/lib/CodeGen/MachineSSAUpdater.cpp b/contrib/llvm/lib/CodeGen/MachineSSAUpdater.cpp
index fd1bf31..71a6eba 100644
--- a/contrib/llvm/lib/CodeGen/MachineSSAUpdater.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineSSAUpdater.cpp
@@ -340,7 +340,7 @@ public:
}
};
-} // namespace llvm
+} // End llvm namespace
/// GetValueAtEndOfBlockInternal - Check to see if AvailableVals has an entry
/// for the specified BB and if so, return it. If not, construct SSA form by
diff --git a/contrib/llvm/lib/CodeGen/MachineScheduler.cpp b/contrib/llvm/lib/CodeGen/MachineScheduler.cpp
index dd7654b..a48e54c 100644
--- a/contrib/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -1262,7 +1262,7 @@ public:
protected:
void clusterNeighboringLoads(ArrayRef<SUnit*> Loads, ScheduleDAGMI *DAG);
};
-} // namespace
+} // anonymous
void LoadClusterMutation::clusterNeighboringLoads(ArrayRef<SUnit*> Loads,
ScheduleDAGMI *DAG) {
@@ -1355,7 +1355,7 @@ public:
void apply(ScheduleDAGMI *DAG) override;
};
-} // namespace
+} // anonymous
/// \brief Callback from DAG postProcessing to create cluster edges to encourage
/// fused operations.
@@ -1407,7 +1407,7 @@ public:
protected:
void constrainLocalCopy(SUnit *CopySU, ScheduleDAGMILive *DAG);
};
-} // namespace
+} // anonymous
/// constrainLocalCopy handles two possibilities:
/// 1) Local src:
diff --git a/contrib/llvm/lib/CodeGen/MachineTraceMetrics.cpp b/contrib/llvm/lib/CodeGen/MachineTraceMetrics.cpp
index 7704d14..f9adba0 100644
--- a/contrib/llvm/lib/CodeGen/MachineTraceMetrics.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineTraceMetrics.cpp
@@ -306,7 +306,7 @@ public:
MinInstrCountEnsemble(MachineTraceMetrics *mtm)
: MachineTraceMetrics::Ensemble(mtm) {}
};
-} // namespace
+}
// Select the preferred predecessor for MBB.
const MachineBasicBlock*
@@ -414,7 +414,7 @@ struct LoopBounds {
const MachineLoopInfo *loops)
: Blocks(blocks), Loops(loops), Downward(false) {}
};
-} // namespace
+}
// Specialize po_iterator_storage in order to prune the post-order traversal so
// it is limited to the current loop and doesn't traverse the loop back edges.
@@ -447,7 +447,7 @@ public:
return LB.Visited.insert(To).second;
}
};
-} // namespace llvm
+}
/// Compute the trace through MBB.
void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
@@ -619,7 +619,7 @@ struct DataDep {
assert((++DefI).atEnd() && "Register has multiple defs");
}
};
-} // namespace
+}
// Get the input data dependencies that must be ready before UseMI can issue.
// Return true if UseMI has any physreg operands.
@@ -681,7 +681,7 @@ struct LiveRegUnit {
LiveRegUnit(unsigned RU) : RegUnit(RU), Cycle(0), MI(nullptr), Op(0) {}
};
-} // namespace
+}
// Identify physreg dependencies for UseMI, and update the live regunit
// tracking set when scanning instructions downwards.
@@ -829,8 +829,7 @@ computeInstrDepths(const MachineBasicBlock *MBB) {
// Filter and process dependencies, computing the earliest issue cycle.
unsigned Cycle = 0;
- for (unsigned i = 0, e = Deps.size(); i != e; ++i) {
- const DataDep &Dep = Deps[i];
+ for (const DataDep &Dep : Deps) {
const TraceBlockInfo&DepTBI =
BlockInfo[Dep.DefMI->getParent()->getNumber()];
// Ignore dependencies from outside the current trace.
@@ -1088,9 +1087,9 @@ computeInstrHeights(const MachineBasicBlock *MBB) {
MTM.SchedModel, MTM.TII, MTM.TRI);
// Update the required height of any virtual registers read by MI.
- for (unsigned i = 0, e = Deps.size(); i != e; ++i)
- if (pushDepHeight(Deps[i], MI, Cycle, Heights, MTM.SchedModel, MTM.TII))
- addLiveIns(Deps[i].DefMI, Deps[i].DefOp, Stack);
+ for (const DataDep &Dep : Deps)
+ if (pushDepHeight(Dep, MI, Cycle, Heights, MTM.SchedModel, MTM.TII))
+ addLiveIns(Dep.DefMI, Dep.DefOp, Stack);
InstrCycles &MICycles = Cycles[MI];
MICycles.Height = Cycle;
@@ -1106,8 +1105,7 @@ computeInstrHeights(const MachineBasicBlock *MBB) {
// Update virtual live-in heights. They were added by addLiveIns() with a 0
// height because the final height isn't known until now.
DEBUG(dbgs() << "BB#" << MBB->getNumber() << " Live-ins:");
- for (unsigned i = 0, e = TBI.LiveIns.size(); i != e; ++i) {
- LiveInReg &LIR = TBI.LiveIns[i];
+ for (LiveInReg &LIR : TBI.LiveIns) {
const MachineInstr *DefMI = MTM.MRI->getVRegDef(LIR.Reg);
LIR.Height = Heights.lookup(DefMI);
DEBUG(dbgs() << ' ' << PrintReg(LIR.Reg) << '@' << LIR.Height);
diff --git a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
index 72a6769..ca35ec5 100644
--- a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -258,7 +258,7 @@ namespace {
}
};
-} // namespace
+}
char MachineVerifierPass::ID = 0;
INITIALIZE_PASS(MachineVerifierPass, "machineverifier",
@@ -1710,7 +1710,7 @@ namespace {
bool EntryIsSetup;
bool ExitIsSetup;
};
-} // namespace
+}
/// Make sure on every path through the CFG, a FrameSetup <n> is always followed
/// by a FrameDestroy <n>, stack adjustments are identical on all
diff --git a/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp b/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp
index 9780d75..a1042e7 100644
--- a/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp
+++ b/contrib/llvm/lib/CodeGen/OptimizePHIs.cpp
@@ -55,7 +55,7 @@ namespace {
bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle);
bool OptimizeBB(MachineBasicBlock &MBB);
};
-} // namespace
+}
char OptimizePHIs::ID = 0;
char &llvm::OptimizePHIsID = OptimizePHIs::ID;
diff --git a/contrib/llvm/lib/CodeGen/PHIElimination.cpp b/contrib/llvm/lib/CodeGen/PHIElimination.cpp
index 471c78a..d343301 100644
--- a/contrib/llvm/lib/CodeGen/PHIElimination.cpp
+++ b/contrib/llvm/lib/CodeGen/PHIElimination.cpp
@@ -104,7 +104,7 @@ namespace {
MachineInstrExpressionTrait> LoweredPHIMap;
LoweredPHIMap LoweredPHIs;
};
-} // namespace
+}
STATISTIC(NumLowered, "Number of phis lowered");
STATISTIC(NumCriticalEdgesSplit, "Number of critical edges split");
diff --git a/contrib/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/contrib/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index 71c0a64..ebe05e3 100644
--- a/contrib/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/contrib/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -293,7 +293,7 @@ namespace {
/// register of the last source.
unsigned getReg() const { return Reg; }
};
-} // namespace
+}
char PeepholeOptimizer::ID = 0;
char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID;
diff --git a/contrib/llvm/lib/CodeGen/PostRASchedulerList.cpp b/contrib/llvm/lib/CodeGen/PostRASchedulerList.cpp
index 6760b5f..6f76116 100644
--- a/contrib/llvm/lib/CodeGen/PostRASchedulerList.cpp
+++ b/contrib/llvm/lib/CodeGen/PostRASchedulerList.cpp
@@ -184,7 +184,7 @@ namespace {
void dumpSchedule() const;
void emitNoop(unsigned CurCycle);
};
-} // namespace
+}
char &llvm::PostRASchedulerID = PostRAScheduler::ID;
diff --git a/contrib/llvm/lib/CodeGen/RegAllocFast.cpp b/contrib/llvm/lib/CodeGen/RegAllocFast.cpp
index 4a46638..fd3d4d7 100644
--- a/contrib/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/contrib/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -194,7 +194,7 @@ namespace {
bool setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg);
};
char RAFast::ID = 0;
-} // namespace
+}
/// getStackSpaceFor - This allocates space for the specified virtual register
/// to be held on the stack.
diff --git a/contrib/llvm/lib/CodeGen/RegisterCoalescer.cpp b/contrib/llvm/lib/CodeGen/RegisterCoalescer.cpp
index e2061fe..7afea2a 100644
--- a/contrib/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/contrib/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -1449,6 +1449,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
<< format("%04X", S.LaneMask) << ")\n");
LIS->shrinkToUses(S, LI.reg);
}
+ LI.removeEmptySubRanges();
}
if (ShrinkMainRange) {
LiveInterval &LI = LIS->getInterval(CP.getDstReg());
@@ -2697,7 +2698,7 @@ struct MBBPriorityInfo {
MBBPriorityInfo(MachineBasicBlock *mbb, unsigned depth, bool issplit)
: MBB(mbb), Depth(depth), IsSplit(issplit) {}
};
-} // namespace
+}
/// C-style comparator that sorts first based on the loop depth of the basic
/// block (the unsigned), and then on the MBB number.
diff --git a/contrib/llvm/lib/CodeGen/RegisterCoalescer.h b/contrib/llvm/lib/CodeGen/RegisterCoalescer.h
index 4ba7441..04067a1 100644
--- a/contrib/llvm/lib/CodeGen/RegisterCoalescer.h
+++ b/contrib/llvm/lib/CodeGen/RegisterCoalescer.h
@@ -111,6 +111,6 @@ namespace llvm {
/// Return the register class of the coalesced register.
const TargetRegisterClass *getNewRC() const { return NewRC; }
};
-} // namespace llvm
+} // End llvm namespace
#endif
diff --git a/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
index ae4b935..390b6d2 100644
--- a/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/contrib/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -574,13 +574,13 @@ static bool MIsNeedChainEdge(AliasAnalysis *AA, const MachineFrameInfo *MFI,
int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset;
int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset;
- AliasAnalysis::AliasResult AAResult =
+ AliasResult AAResult =
AA->alias(MemoryLocation(MMOa->getValue(), Overlapa,
UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
MemoryLocation(MMOb->getValue(), Overlapb,
UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
- return (AAResult != AliasAnalysis::NoAlias);
+ return (AAResult != NoAlias);
}
/// This recursive function iterates over chain deps of SUb looking for
@@ -1508,7 +1508,7 @@ public:
return getCurr()->Preds.end();
}
};
-} // namespace
+} // anonymous
static bool hasDataSucc(const SUnit *SU) {
for (SUnit::const_succ_iterator
diff --git a/contrib/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp b/contrib/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp
index cdf27ae..b2e4617 100644
--- a/contrib/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp
@@ -72,7 +72,7 @@ namespace llvm {
return G->addCustomGraphFeatures(GW);
}
};
-} // namespace llvm
+}
std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
const ScheduleDAG *G) {
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5fea52c..6056d93 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -459,7 +459,7 @@ namespace {
return TLI.getSetCCResultType(*DAG.getContext(), VT);
}
};
-} // namespace
+}
namespace {
@@ -475,7 +475,7 @@ public:
DC.removeFromWorklist(N);
}
};
-} // namespace
+}
//===----------------------------------------------------------------------===//
// TargetLowering::DAGCombinerInfo implementation
@@ -1192,8 +1192,8 @@ bool DAGCombiner::recursivelyDeleteUnusedNodes(SDNode *N) {
continue;
if (N->use_empty()) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- Nodes.insert(N->getOperand(i).getNode());
+ for (const SDValue &ChildN : N->op_values())
+ Nodes.insert(ChildN.getNode());
removeFromWorklist(N);
DAG.DeleteNode(N);
@@ -1266,9 +1266,9 @@ void DAGCombiner::Run(CombineLevel AtLevel) {
// worklist as well. Because the worklist uniques things already, this
// won't repeatedly process the same operand.
CombinedNodes.insert(N);
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (!CombinedNodes.count(N->getOperand(i).getNode()))
- AddToWorklist(N->getOperand(i).getNode());
+ for (const SDValue &ChildN : N->op_values())
+ if (!CombinedNodes.count(ChildN.getNode()))
+ AddToWorklist(ChildN.getNode());
SDValue RV = combine(N);
@@ -1523,8 +1523,7 @@ SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
SDNode *TF = TFs[i];
// Check each of the operands.
- for (unsigned i = 0, ie = TF->getNumOperands(); i != ie; ++i) {
- SDValue Op = TF->getOperand(i);
+ for (const SDValue &Op : TF->op_values()) {
switch (Op.getOpcode()) {
case ISD::EntryToken:
@@ -2179,7 +2178,11 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
}
// fold (sdiv X, pow2) -> simple ops after legalize
+ // FIXME: We check for the exact bit here because the generic lowering gives
+ // better results in that case. The target-specific lowering should learn how
+ // to handle exact sdivs efficiently.
if (N1C && !N1C->isNullValue() && !N1C->isOpaque() &&
+ !cast<BinaryWithFlagsSDNode>(N)->Flags.hasExact() &&
(N1C->getAPIntValue().isPowerOf2() ||
(-N1C->getAPIntValue()).isPowerOf2())) {
// If dividing by powers of two is cheap, then don't perform the following
@@ -4275,7 +4278,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
if (isNullConstant(N0))
return N0;
// fold (shl x, c >= size(x)) -> undef
- if (N1C && N1C->getZExtValue() >= OpSizeInBits)
+ if (N1C && N1C->getAPIntValue().uge(OpSizeInBits))
return DAG.getUNDEF(VT);
// fold (shl x, 0) -> x
if (N1C && N1C->isNullValue())
@@ -4362,6 +4365,22 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
}
}
+ // fold (shl (sr[la] exact X, C1), C2) -> (shl X, (C2-C1)) if C1 <= C2
+ // fold (shl (sr[la] exact X, C1), C2) -> (sr[la] X, (C2-C1)) if C1 > C2
+ if (N1C && (N0.getOpcode() == ISD::SRL || N0.getOpcode() == ISD::SRA) &&
+ cast<BinaryWithFlagsSDNode>(N0)->Flags.hasExact()) {
+ if (ConstantSDNode *N0C1 = isConstOrConstSplat(N0.getOperand(1))) {
+ uint64_t C1 = N0C1->getZExtValue();
+ uint64_t C2 = N1C->getZExtValue();
+ SDLoc DL(N);
+ if (C1 <= C2)
+ return DAG.getNode(ISD::SHL, DL, VT, N0.getOperand(0),
+ DAG.getConstant(C2 - C1, DL, N1.getValueType()));
+ return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0),
+ DAG.getConstant(C1 - C2, DL, N1.getValueType()));
+ }
+ }
+
// fold (shl (srl x, c1), c2) -> (and (shl x, (sub c2, c1), MASK) or
// (and (srl x, (sub c1, c2), MASK)
// Only fold this if the inner shift has no other uses -- if it does, folding
@@ -5560,12 +5579,12 @@ SDValue DAGCombiner::visitSETCC(SDNode *N) {
SDLoc(N));
}
-// tryToFoldExtendOfConstant - Try to fold a sext/zext/aext
-// dag node into a ConstantSDNode or a build_vector of constants.
-// This function is called by the DAGCombiner when visiting sext/zext/aext
-// dag nodes (see for example method DAGCombiner::visitSIGN_EXTEND).
-// Vector extends are not folded if operations are legal; this is to
-// avoid introducing illegal build_vector dag nodes.
+/// Try to fold a sext/zext/aext dag node into a ConstantSDNode or
+/// a build_vector of constants.
+/// This function is called by the DAGCombiner when visiting sext/zext/aext
+/// dag nodes (see for example method DAGCombiner::visitSIGN_EXTEND).
+/// Vector extends are not folded if operations are legal; this is to
+/// avoid introducing illegal build_vector dag nodes.
static SDNode *tryToFoldExtendOfConstant(SDNode *N, const TargetLowering &TLI,
SelectionDAG &DAG, bool LegalTypes,
bool LegalOperations) {
@@ -5595,7 +5614,6 @@ static SDNode *tryToFoldExtendOfConstant(SDNode *N, const TargetLowering &TLI,
// We can fold this node into a build_vector.
unsigned VTBits = SVT.getSizeInBits();
unsigned EVTBits = N0->getValueType(0).getScalarType().getSizeInBits();
- unsigned ShAmt = VTBits - EVTBits;
SmallVector<SDValue, 8> Elts;
unsigned NumElts = VT.getVectorNumElements();
SDLoc DL(N);
@@ -5608,14 +5626,13 @@ static SDNode *tryToFoldExtendOfConstant(SDNode *N, const TargetLowering &TLI,
}
SDLoc DL(Op);
- ConstantSDNode *CurrentND = cast<ConstantSDNode>(Op);
- const APInt &C = APInt(VTBits, CurrentND->getAPIntValue().getZExtValue());
+ // Get the constant value and if needed trunc it to the size of the type.
+ // Nodes like build_vector might have constants wider than the scalar type.
+ APInt C = cast<ConstantSDNode>(Op)->getAPIntValue().zextOrTrunc(EVTBits);
if (Opcode == ISD::SIGN_EXTEND || Opcode == ISD::SIGN_EXTEND_VECTOR_INREG)
- Elts.push_back(DAG.getConstant(C.shl(ShAmt).ashr(ShAmt).getZExtValue(),
- DL, SVT));
+ Elts.push_back(DAG.getConstant(C.sext(VTBits), DL, SVT));
else
- Elts.push_back(DAG.getConstant(C.shl(ShAmt).lshr(ShAmt).getZExtValue(),
- DL, SVT));
+ Elts.push_back(DAG.getConstant(C.zext(VTBits), DL, SVT));
}
return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Elts).getNode();
@@ -7307,8 +7324,7 @@ ConstantFoldBITCASTofBUILD_VECTOR(SDNode *BV, EVT DstEltVT) {
DstEltVT, BV->getOperand(0)));
SmallVector<SDValue, 8> Ops;
- for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
- SDValue Op = BV->getOperand(i);
+ for (SDValue Op : BV->op_values()) {
// If the vector element type is not legal, the BUILD_VECTOR operands
// are promoted and implicitly truncated. Make that explicit here.
if (Op.getValueType() != SrcEltVT)
@@ -7383,13 +7399,13 @@ ConstantFoldBITCASTofBUILD_VECTOR(SDNode *BV, EVT DstEltVT) {
NumOutputsPerInput*BV->getNumOperands());
SmallVector<SDValue, 8> Ops;
- for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
- if (BV->getOperand(i).getOpcode() == ISD::UNDEF) {
+ for (const SDValue &Op : BV->op_values()) {
+ if (Op.getOpcode() == ISD::UNDEF) {
Ops.append(NumOutputsPerInput, DAG.getUNDEF(DstEltVT));
continue;
}
- APInt OpVal = cast<ConstantSDNode>(BV->getOperand(i))->
+ APInt OpVal = cast<ConstantSDNode>(Op)->
getAPIntValue().zextOrTrunc(SrcBitSize);
for (unsigned j = 0; j != NumOutputsPerInput; ++j) {
@@ -9954,7 +9970,7 @@ struct LoadedSlice {
return true;
}
};
-} // namespace
+}
/// \brief Check that all bits set in \p UsedBits form a dense region, i.e.,
/// \p UsedBits looks like 0..0 1..1 0..0.
@@ -10218,8 +10234,8 @@ CheckForMaskedLoad(SDValue V, SDValue Ptr, SDValue Chain) {
return Result; // Fail.
else {
bool isOk = false;
- for (unsigned i = 0, e = Chain->getNumOperands(); i != e; ++i)
- if (Chain->getOperand(i).getNode() == LD) {
+ for (const SDValue &ChainOp : Chain->op_values())
+ if (ChainOp.getNode() == LD) {
isOk = true;
break;
}
@@ -13884,12 +13900,12 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const {
Op0->getSrcValueOffset() - MinOffset;
int64_t Overlap2 = (Op1->getMemoryVT().getSizeInBits() >> 3) +
Op1->getSrcValueOffset() - MinOffset;
- AliasAnalysis::AliasResult AAResult =
+ AliasResult AAResult =
AA.alias(MemoryLocation(Op0->getMemOperand()->getValue(), Overlap1,
UseTBAA ? Op0->getAAInfo() : AAMDNodes()),
MemoryLocation(Op1->getMemOperand()->getValue(), Overlap2,
UseTBAA ? Op1->getAAInfo() : AAMDNodes()));
- if (AAResult == AliasAnalysis::NoAlias)
+ if (AAResult == NoAlias)
return false;
}
@@ -13915,8 +13931,7 @@ void DAGCombiner::GatherAllAliases(SDNode *N, SDValue OriginalChain,
// aliases list. If not, then continue up the chain looking for the next
// candidate.
while (!Chains.empty()) {
- SDValue Chain = Chains.back();
- Chains.pop_back();
+ SDValue Chain = Chains.pop_back_val();
// For TokenFactor nodes, look at each operand and only continue up the
// chain until we find two aliases. If we've seen two aliases, assume we'll
@@ -14023,7 +14038,7 @@ void DAGCombiner::GatherAllAliases(SDNode *N, SDValue OriginalChain,
UIE = M->use_end(); UI != UIE; ++UI)
if (UI.getUse().getValueType() == MVT::Other &&
Visited.insert(*UI).second) {
- if (isa<MemIntrinsicSDNode>(*UI) || isa<MemSDNode>(*UI)) {
+ if (isa<MemSDNode>(*UI)) {
// We've not visited this use, and we care about it (it could have an
// ordering dependency with the original node).
Aliases.clear();
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 0351c33..5452b17 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -59,6 +59,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -701,6 +702,15 @@ bool FastISel::lowerCallOperands(const CallInst *CI, unsigned ArgIdx,
return lowerCallTo(CLI);
}
+FastISel::CallLoweringInfo &FastISel::CallLoweringInfo::setCallee(
+ const DataLayout &DL, MCContext &Ctx, CallingConv::ID CC, Type *ResultTy,
+ const char *Target, ArgListTy &&ArgsList, unsigned FixedArgs) {
+ SmallString<32> MangledName;
+ Mangler::getNameWithPrefix(MangledName, Target, DL);
+ MCSymbol *Sym = Ctx.getOrCreateSymbol(MangledName);
+ return setCallee(CC, ResultTy, Sym, std::move(ArgsList), FixedArgs);
+}
+
bool FastISel::selectPatchpoint(const CallInst *I) {
// void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>,
// i32 <numBytes>,
@@ -856,6 +866,15 @@ static AttributeSet getReturnAttrs(FastISel::CallLoweringInfo &CLI) {
bool FastISel::lowerCallTo(const CallInst *CI, const char *SymName,
unsigned NumArgs) {
+ MCContext &Ctx = MF->getContext();
+ SmallString<32> MangledName;
+ Mangler::getNameWithPrefix(MangledName, SymName, DL);
+ MCSymbol *Sym = Ctx.getOrCreateSymbol(MangledName);
+ return lowerCallTo(CI, Sym, NumArgs);
+}
+
+bool FastISel::lowerCallTo(const CallInst *CI, MCSymbol *Symbol,
+ unsigned NumArgs) {
ImmutableCallSite CS(CI);
PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
@@ -880,7 +899,7 @@ bool FastISel::lowerCallTo(const CallInst *CI, const char *SymName,
}
CallLoweringInfo CLI;
- CLI.setCallee(RetTy, FTy, SymName, std::move(Args), CS, NumArgs);
+ CLI.setCallee(RetTy, FTy, Symbol, std::move(Args), CS, NumArgs);
return lowerCallTo(CLI);
}
@@ -1331,7 +1350,7 @@ bool FastISel::selectInstruction(const Instruction *I) {
// Don't handle Intrinsic::trap if a trap funciton is specified.
if (F && F->getIntrinsicID() == Intrinsic::trap &&
- !TM.Options.getTrapFunctionName().empty())
+ Call->hasFnAttr("trap-func-name"))
return false;
}
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 7abc0c4..42595cb 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -422,6 +422,8 @@ void InstrEmitter::AddOperand(MachineInstrBuilder &MIB,
MIB.addConstantPoolIndex(Idx, Offset, CP->getTargetFlags());
} else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
MIB.addExternalSymbol(ES->getSymbol(), ES->getTargetFlags());
+ } else if (auto *SymNode = dyn_cast<MCSymbolSDNode>(Op)) {
+ MIB.addSym(SymNode->getMCSymbol());
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) {
MIB.addBlockAddress(BA->getBlockAddress(),
BA->getOffset(),
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h b/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h
index 2a61914..3b24d93 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h
@@ -26,7 +26,7 @@ class MachineInstrBuilder;
class MCInstrDesc;
class SDDbgValue;
-class InstrEmitter {
+class LLVM_LIBRARY_VISIBILITY InstrEmitter {
MachineFunction *MF;
MachineRegisterInfo *MRI;
const TargetInstrInfo *TII;
@@ -140,6 +140,6 @@ private:
DenseMap<SDValue, unsigned> &VRBaseMap);
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 37f95e5..c0d7871 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -198,7 +198,7 @@ public:
ReplacedNode(Old);
}
};
-} // namespace
+}
/// Return a vector shuffle operation which
/// performs the same shuffe in terms of order or result bytes, but on a type
@@ -1165,17 +1165,18 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
if (Node->getOpcode() == ISD::TargetConstant) // Allow illegal target nodes.
return;
+#ifndef NDEBUG
for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
assert(TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) ==
TargetLowering::TypeLegal &&
"Unexpected illegal type!");
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
+ for (const SDValue &Op : Node->op_values())
assert((TLI.getTypeAction(*DAG.getContext(),
- Node->getOperand(i).getValueType()) ==
- TargetLowering::TypeLegal ||
- Node->getOperand(i).getOpcode() == ISD::TargetConstant) &&
- "Unexpected illegal type!");
+ Op.getValueType()) == TargetLowering::TypeLegal ||
+ Op.getOpcode() == ISD::TargetConstant) &&
+ "Unexpected illegal type!");
+#endif
// Figure out the correct action; the way to query this varies by opcode
TargetLowering::LegalizeAction Action = TargetLowering::Legal;
@@ -2047,10 +2048,11 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
bool isSigned) {
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
- EVT ArgVT = Node->getOperand(i).getValueType();
+ for (const SDValue &Op : Node->op_values()) {
+ EVT ArgVT = Op.getValueType();
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
- Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy;
+ Entry.Node = Op;
+ Entry.Ty = ArgTy;
Entry.isSExt = isSigned;
Entry.isZExt = !isSigned;
Args.push_back(Entry);
@@ -2256,10 +2258,11 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
- EVT ArgVT = Node->getOperand(i).getValueType();
+ for (const SDValue &Op : Node->op_values()) {
+ EVT ArgVT = Op.getValueType();
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
- Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy;
+ Entry.Node = Op;
+ Entry.Ty = ArgTy;
Entry.isSExt = isSigned;
Entry.isZExt = !isSigned;
Args.push_back(Entry);
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 96e2ff8..f41202c 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -2435,10 +2435,10 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- EVT ArgVT = N->getOperand(i).getValueType();
+ for (const SDValue &Op : N->op_values()) {
+ EVT ArgVT = Op.getValueType();
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
- Entry.Node = N->getOperand(i);
+ Entry.Node = Op;
Entry.Ty = ArgTy;
Entry.isSExt = true;
Entry.isZExt = false;
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index c3e3b7c..9c29769 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -676,7 +676,7 @@ namespace {
NodesToAnalyze.insert(N);
}
};
-} // namespace
+}
/// ReplaceValueWith - The specified value was legalized to the specified other
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 50ad239..ee844a8 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -191,8 +191,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
// Legalize the operands
SmallVector<SDValue, 8> Ops;
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
- Ops.push_back(LegalizeOp(Node->getOperand(i)));
+ for (const SDValue &Op : Node->op_values())
+ Ops.push_back(LegalizeOp(Op));
SDValue Result = SDValue(DAG.UpdateNodeOperands(Op.getNode(), Ops), 0);
@@ -1010,7 +1010,7 @@ SDValue VectorLegalizer::UnrollVSETCC(SDValue Op) {
return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops);
}
-} // namespace
+}
bool SelectionDAG::LegalizeVectors() {
return VectorLegalizer(*this).Run();
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 445e882..905492c 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1760,8 +1760,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) {
// a new CONCAT_VECTORS node with elements that are half-wide.
SmallVector<SDValue, 32> Elts;
EVT EltVT = N->getValueType(0).getVectorElementType();
- for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) {
- SDValue Op = N->getOperand(op);
+ for (const SDValue &Op : N->op_values()) {
for (unsigned i = 0, e = Op.getValueType().getVectorNumElements();
i != e; ++i) {
Elts.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT,
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h b/contrib/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
index 9493532..c27f8de 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
@@ -119,6 +119,6 @@ public:
bool isInvalidated() const { return Invalid; }
};
-} // namespace llvm
+} // end llvm namespace
#endif
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index 61a3fd7..00cbae3 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -227,8 +227,7 @@ SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
else if (VT == MVT::Other)
TryUnfold = true;
}
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- const SDValue &Op = N->getOperand(i);
+ for (const SDValue &Op : N->op_values()) {
MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
if (VT == MVT::Glue)
return nullptr;
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index fd0fa31..e9bd520 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -415,8 +415,8 @@ static bool IsChainDependent(SDNode *Outer, SDNode *Inner,
// to get to the CALLSEQ_BEGIN, but we need to find the path with the
// most nesting in order to ensure that we find the corresponding match.
if (N->getOpcode() == ISD::TokenFactor) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (IsChainDependent(N->getOperand(i).getNode(), Inner, NestLevel, TII))
+ for (const SDValue &Op : N->op_values())
+ if (IsChainDependent(Op.getNode(), Inner, NestLevel, TII))
return true;
return false;
}
@@ -433,9 +433,9 @@ static bool IsChainDependent(SDNode *Outer, SDNode *Inner,
}
}
// Otherwise, find the chain and continue climbing.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (N->getOperand(i).getValueType() == MVT::Other) {
- N = N->getOperand(i).getNode();
+ for (const SDValue &Op : N->op_values())
+ if (Op.getValueType() == MVT::Other) {
+ N = Op.getNode();
goto found_chain_operand;
}
return false;
@@ -464,10 +464,10 @@ FindCallSeqStart(SDNode *N, unsigned &NestLevel, unsigned &MaxNest,
if (N->getOpcode() == ISD::TokenFactor) {
SDNode *Best = nullptr;
unsigned BestMaxNest = MaxNest;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ for (const SDValue &Op : N->op_values()) {
unsigned MyNestLevel = NestLevel;
unsigned MyMaxNest = MaxNest;
- if (SDNode *New = FindCallSeqStart(N->getOperand(i).getNode(),
+ if (SDNode *New = FindCallSeqStart(Op.getNode(),
MyNestLevel, MyMaxNest, TII))
if (!Best || (MyMaxNest > BestMaxNest)) {
Best = New;
@@ -493,9 +493,9 @@ FindCallSeqStart(SDNode *N, unsigned &NestLevel, unsigned &MaxNest,
}
}
// Otherwise, find the chain and continue climbing.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (N->getOperand(i).getValueType() == MVT::Other) {
- N = N->getOperand(i).getNode();
+ for (const SDValue &Op : N->op_values())
+ if (Op.getValueType() == MVT::Other) {
+ N = Op.getNode();
goto found_chain_operand;
}
return nullptr;
@@ -848,17 +848,26 @@ void ScheduleDAGRRList::UnscheduleNodeBottomUp(SUnit *SU) {
}
}
- for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
- I != E; ++I) {
- if (I->isAssignedRegDep()) {
- if (!LiveRegDefs[I->getReg()])
+ for (auto &Succ : SU->Succs) {
+ if (Succ.isAssignedRegDep()) {
+ auto Reg = Succ.getReg();
+ if (!LiveRegDefs[Reg])
++NumLiveRegs;
// This becomes the nearest def. Note that an earlier def may still be
// pending if this is a two-address node.
- LiveRegDefs[I->getReg()] = SU;
- if (LiveRegGens[I->getReg()] == nullptr ||
- I->getSUnit()->getHeight() < LiveRegGens[I->getReg()]->getHeight())
- LiveRegGens[I->getReg()] = I->getSUnit();
+ LiveRegDefs[Reg] = SU;
+
+ // Update LiveRegGen only if was empty before this unscheduling.
+ // This is to avoid incorrect updating LiveRegGen set in previous run.
+ if (!LiveRegGens[Reg]) {
+ // Find the successor with the lowest height.
+ LiveRegGens[Reg] = Succ.getSUnit();
+ for (auto &Succ2 : SU->Succs) {
+ if (Succ2.isAssignedRegDep() && Succ2.getReg() == Reg &&
+ Succ2.getSUnit()->getHeight() < LiveRegGens[Reg]->getHeight())
+ LiveRegGens[Reg] = Succ2.getSUnit();
+ }
+ }
}
}
if (SU->getHeight() < MinAvailableCycle)
@@ -951,8 +960,7 @@ SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
else if (VT == MVT::Other)
TryUnfold = true;
}
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- const SDValue &Op = N->getOperand(i);
+ for (const SDValue &Op : N->op_values()) {
MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());
if (VT == MVT::Glue)
return nullptr;
@@ -1247,10 +1255,9 @@ static void CheckForLiveRegDefMasked(SUnit *SU, const uint32_t *RegMask,
/// getNodeRegMask - Returns the register mask attached to an SDNode, if any.
static const uint32_t *getNodeRegMask(const SDNode *N) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (const RegisterMaskSDNode *Op =
- dyn_cast<RegisterMaskSDNode>(N->getOperand(i).getNode()))
- return Op->getRegMask();
+ for (const SDValue &Op : N->op_values())
+ if (const auto *RegOp = dyn_cast<RegisterMaskSDNode>(Op.getNode()))
+ return RegOp->getRegMask();
return nullptr;
}
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index f4c7b59..b22d6ed 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -332,9 +332,9 @@ void ScheduleDAGSDNodes::BuildSchedUnits() {
SDNode *NI = Worklist.pop_back_val();
// Add all operands to the worklist unless they've already been added.
- for (unsigned i = 0, e = NI->getNumOperands(); i != e; ++i)
- if (Visited.insert(NI->getOperand(i).getNode()).second)
- Worklist.push_back(NI->getOperand(i).getNode());
+ for (const SDValue &Op : NI->op_values())
+ if (Visited.insert(Op.getNode()).second)
+ Worklist.push_back(Op.getNode());
if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate.
continue;
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
index 4c74182..159c28c 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
@@ -64,6 +64,7 @@ namespace llvm {
if (isa<TargetIndexSDNode>(Node)) return true;
if (isa<JumpTableSDNode>(Node)) return true;
if (isa<ExternalSymbolSDNode>(Node)) return true;
+ if (isa<MCSymbolSDNode>(Node)) return true;
if (isa<BlockAddressSDNode>(Node)) return true;
if (Node->getOpcode() == ISD::EntryToken ||
isa<MDNodeSDNode>(Node)) return true;
@@ -180,6 +181,6 @@ namespace llvm {
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap,
MachineBasicBlock::iterator InsertPos);
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0eff930..be54782 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -187,8 +187,7 @@ bool ISD::isBuildVectorOfConstantSDNodes(const SDNode *N) {
if (N->getOpcode() != ISD::BUILD_VECTOR)
return false;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- SDValue Op = N->getOperand(i);
+ for (const SDValue &Op : N->op_values()) {
if (Op.getOpcode() == ISD::UNDEF)
continue;
if (!isa<ConstantSDNode>(Op))
@@ -203,8 +202,7 @@ bool ISD::isBuildVectorOfConstantFPSDNodes(const SDNode *N) {
if (N->getOpcode() != ISD::BUILD_VECTOR)
return false;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- SDValue Op = N->getOperand(i);
+ for (const SDValue &Op : N->op_values()) {
if (Op.getOpcode() == ISD::UNDEF)
continue;
if (!isa<ConstantFPSDNode>(Op))
@@ -244,8 +242,8 @@ bool ISD::allOperandsUndef(const SDNode *N) {
if (N->getNumOperands() == 0)
return false;
- for (unsigned i = 0, e = N->getNumOperands(); i != e ; ++i)
- if (N->getOperand(i).getOpcode() != ISD::UNDEF)
+ for (const SDValue &Op : N->op_values())
+ if (Op.getOpcode() != ISD::UNDEF)
return false;
return true;
@@ -427,12 +425,12 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, unsigned short OpC,
AddNodeIDOperands(ID, OpList);
}
-/// AddNodeIDCustom - If this is an SDNode with special info, add this info to
-/// the NodeID data.
+/// If this is an SDNode with special info, add this info to the NodeID data.
static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
switch (N->getOpcode()) {
case ISD::TargetExternalSymbol:
case ISD::ExternalSymbol:
+ case ISD::MCSymbol:
llvm_unreachable("Should only be used on nodes with operands");
default: break; // Normal nodes don't need extra info.
case ISD::TargetConstant:
@@ -797,6 +795,11 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
ESN->getTargetFlags()));
break;
}
+ case ISD::MCSymbol: {
+ auto *MCSN = cast<MCSymbolSDNode>(N);
+ Erased = MCSymbols.erase(MCSN->getMCSymbol());
+ break;
+ }
case ISD::VALUETYPE: {
EVT VT = cast<VTSDNode>(N)->getVT();
if (VT.isExtended()) {
@@ -1014,6 +1017,7 @@ void SelectionDAG::clear() {
ExtendedValueTypeNodes.clear();
ExternalSymbols.clear();
TargetExternalSymbols.clear();
+ MCSymbols.clear();
std::fill(CondCodeNodes.begin(), CondCodeNodes.end(),
static_cast<CondCodeSDNode*>(nullptr));
std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(),
@@ -1469,6 +1473,15 @@ SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) {
return SDValue(N, 0);
}
+SDValue SelectionDAG::getMCSymbol(MCSymbol *Sym, EVT VT) {
+ SDNode *&N = MCSymbols[Sym];
+ if (N)
+ return SDValue(N, 0);
+ N = new (NodeAllocator) MCSymbolSDNode(Sym, VT);
+ InsertNode(N);
+ return SDValue(N, 0);
+}
+
SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, EVT VT,
unsigned char TargetFlags) {
SDNode *&N =
@@ -6134,7 +6147,7 @@ public:
: SelectionDAG::DAGUpdateListener(d), UI(ui), UE(ue) {}
};
-} // namespace
+}
/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG.
@@ -6344,7 +6357,7 @@ namespace {
bool operator<(const UseMemo &L, const UseMemo &R) {
return (intptr_t)L.User < (intptr_t)R.User;
}
-} // namespace
+}
/// ReplaceAllUsesOfValuesWith - Replace any uses of From with To, leaving
/// uses of other values produced by From.getNode() alone. The same value
@@ -6589,7 +6602,7 @@ namespace {
VTs.push_back(MVT((MVT::SimpleValueType)i));
}
};
-} // namespace
+}
static ManagedStatic<std::set<EVT, EVT::compareRawBits> > EVTs;
static ManagedStatic<EVTArray> SimpleVTArray;
@@ -6659,8 +6672,8 @@ bool SDNode::isOnlyUserOf(SDNode *N) const {
/// isOperand - Return true if this node is an operand of N.
///
bool SDValue::isOperandOf(SDNode *N) const {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (*this == N->getOperand(i))
+ for (const SDValue &Op : N->op_values())
+ if (*this == Op)
return true;
return false;
}
@@ -6728,8 +6741,8 @@ SDNode::hasPredecessorHelper(const SDNode *N,
// Haven't visited N yet. Continue the search.
while (!Worklist.empty()) {
const SDNode *M = Worklist.pop_back_val();
- for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) {
- SDNode *Op = M->getOperand(i).getNode();
+ for (const SDValue &OpV : M->op_values()) {
+ SDNode *Op = OpV.getNode();
if (Visited.insert(Op).second)
Worklist.push_back(Op);
if (Op == N)
@@ -7078,8 +7091,8 @@ BuildVectorSDNode::getConstantFPSplatNode(BitVector *UndefElements) const {
}
bool BuildVectorSDNode::isConstant() const {
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- unsigned Opc = getOperand(i).getOpcode();
+ for (const SDValue &Op : op_values()) {
+ unsigned Opc = Op.getOpcode();
if (Opc != ISD::UNDEF && Opc != ISD::Constant && Opc != ISD::ConstantFP)
return false;
}
@@ -7120,8 +7133,8 @@ static void checkForCyclesHelper(const SDNode *N,
abort();
}
- for(unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- checkForCyclesHelper(N->getOperand(i).getNode(), Visited, Checked, DAG);
+ for (const SDValue &Op : N->op_values())
+ checkForCyclesHelper(Op.getNode(), Visited, Checked, DAG);
Checked.insert(N);
Visited.erase(N);
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 8313a48..4897082 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -261,8 +261,9 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, SDLoc DL,
assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
NumParts = NumRegs; // Silence a compiler warning.
assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
- assert(RegisterVT == Parts[0].getSimpleValueType() &&
- "Part type doesn't match part!");
+ assert(RegisterVT.getSizeInBits() ==
+ Parts[0].getSimpleValueType().getSizeInBits() &&
+ "Part type sizes don't match!");
// Assemble the parts into intermediate operands.
SmallVector<SDValue, 8> Ops(NumIntermediates);
@@ -1445,8 +1446,8 @@ void SelectionDAGBuilder::FindMergedConditions(const Value *Cond,
// We have flexibility in setting Prob for BB1 and Prob for TmpBB.
// The requirement is that
// TrueProb for BB1 + (FalseProb for BB1 * TrueProb for TmpBB)
- // = TrueProb for orignal BB.
- // Assuming the orignal weights are A and B, one choice is to set BB1's
+ // = TrueProb for original BB.
+ // Assuming the original weights are A and B, one choice is to set BB1's
// weights to A and A+2B, and set TmpBB's weights to A and 2B. This choice
// assumes that
// TrueProb for BB1 == FalseProb for BB1 * TrueProb for TmpBB.
@@ -1481,8 +1482,8 @@ void SelectionDAGBuilder::FindMergedConditions(const Value *Cond,
// We have flexibility in setting Prob for BB1 and Prob for TmpBB.
// The requirement is that
// FalseProb for BB1 + (TrueProb for BB1 * FalseProb for TmpBB)
- // = FalseProb for orignal BB.
- // Assuming the orignal weights are A and B, one choice is to set BB1's
+ // = FalseProb for original BB.
+ // Assuming the original weights are A and B, one choice is to set BB1's
// weights to 2A+B and B, and set TmpBB's weights to 2A and B. This choice
// assumes that
// FalseProb for BB1 == TrueProb for BB1 * FalseProb for TmpBB.
@@ -2238,17 +2239,11 @@ void SelectionDAGBuilder::visitSDiv(const User &I) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
- // Turn exact SDivs into multiplications.
- // FIXME: This should be in DAGCombiner, but it doesn't have access to the
- // exact bit.
- if (isa<BinaryOperator>(&I) && cast<BinaryOperator>(&I)->isExact() &&
- !isa<ConstantSDNode>(Op1) &&
- isa<ConstantSDNode>(Op2) && !cast<ConstantSDNode>(Op2)->isNullValue())
- setValue(&I, DAG.getTargetLoweringInfo()
- .BuildExactSDIV(Op1, Op2, getCurSDLoc(), DAG));
- else
- setValue(&I, DAG.getNode(ISD::SDIV, getCurSDLoc(), Op1.getValueType(),
- Op1, Op2));
+ SDNodeFlags Flags;
+ Flags.setExact(isa<PossiblyExactOperator>(&I) &&
+ cast<PossiblyExactOperator>(&I)->isExact());
+ setValue(&I, DAG.getNode(ISD::SDIV, getCurSDLoc(), Op1.getValueType(), Op1,
+ Op2, &Flags));
}
void SelectionDAGBuilder::visitICmp(const User &I) {
@@ -4786,7 +4781,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
case Intrinsic::debugtrap:
case Intrinsic::trap: {
- StringRef TrapFuncName = TM.Options.getTrapFunctionName();
+ StringRef TrapFuncName =
+ I.getAttributes()
+ .getAttribute(AttributeSet::FunctionIndex, "trap-func-name")
+ .getValueAsString();
if (TrapFuncName.empty()) {
ISD::NodeType Op = (Intrinsic == Intrinsic::trap) ?
ISD::TRAP : ISD::DEBUGTRAP;
@@ -4976,11 +4974,9 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(
GlobalValue::getRealLinkageName(Fn->getName()), IdxVal);
- // Create a TargetExternalSymbol for the label to avoid any target lowering
+ // Create a MCSymbol for the label to avoid any target lowering
// that would make this PC relative.
- StringRef Name = FrameAllocSym->getName();
- assert(Name.data()[Name.size()] == '\0' && "not null terminated");
- SDValue OffsetSym = DAG.getTargetExternalSymbol(Name.data(), PtrVT);
+ SDValue OffsetSym = DAG.getMCSymbol(FrameAllocSym, PtrVT);
SDValue OffsetVal =
DAG.getNode(ISD::FRAME_ALLOC_RECOVER, sdl, PtrVT, OffsetSym);
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 96ee899..ef468a2 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -130,6 +130,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::TargetJumpTable: return "TargetJumpTable";
case ISD::TargetConstantPool: return "TargetConstantPool";
case ISD::TargetExternalSymbol: return "TargetExternalSymbol";
+ case ISD::MCSymbol: return "MCSymbol";
case ISD::TargetBlockAddress: return "TargetBlockAddress";
case ISD::CopyToReg: return "CopyToReg";
@@ -545,12 +546,12 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
}
static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) {
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (N->getOperand(i).getNode()->hasOneUse())
- DumpNodes(N->getOperand(i).getNode(), indent+2, G);
+ for (const SDValue &Op : N->op_values())
+ if (Op.getNode()->hasOneUse())
+ DumpNodes(Op.getNode(), indent+2, G);
else
dbgs() << "\n" << std::string(indent+2, ' ')
- << (void*)N->getOperand(i).getNode() << ": <multiple use>";
+ << (void*)Op.getNode() << ": <multiple use>";
dbgs() << '\n';
dbgs().indent(indent);
@@ -607,10 +608,8 @@ static void DumpNodesr(raw_ostream &OS, const SDNode *N, unsigned indent,
OS << "\n";
// Dump children that have grandchildren on their own line(s).
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- const SDNode *child = N->getOperand(i).getNode();
- DumpNodesr(OS, child, indent+2, G, once);
- }
+ for (const SDValue &Op : N->op_values())
+ DumpNodesr(OS, Op.getNode(), indent+2, G, once);
}
void SDNode::dumpr() const {
@@ -636,12 +635,12 @@ static void printrWithDepthHelper(raw_ostream &OS, const SDNode *N,
if (depth < 1)
return;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ for (const SDValue &Op : N->op_values()) {
// Don't follow chain operands.
- if (N->getOperand(i).getValueType() == MVT::Other)
+ if (Op.getValueType() == MVT::Other)
continue;
OS << '\n';
- printrWithDepthHelper(OS, N->getOperand(i).getNode(), G, depth-1, indent+2);
+ printrWithDepthHelper(OS, Op.getNode(), G, depth-1, indent+2);
}
}
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index c5562cd..31f8210 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -307,7 +307,7 @@ namespace llvm {
"Unknown sched type!");
return createILPListDAGScheduler(IS, OptLevel);
}
-} // namespace llvm
+}
// EmitInstrWithCustomInserter - This method should be implemented by targets
// that mark instructions with the 'usesCustomInserter' flag. These
@@ -637,9 +637,9 @@ void SelectionDAGISel::ComputeLiveOutVRegInfo() {
continue;
// Otherwise, add all chain operands to the worklist.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (N->getOperand(i).getValueType() == MVT::Other)
- Worklist.push_back(N->getOperand(i).getNode());
+ for (const SDValue &Op : N->op_values())
+ if (Op.getValueType() == MVT::Other)
+ Worklist.push_back(Op.getNode());
// If this is a CopyToReg with a vreg dest, process it.
if (N->getOpcode() != ISD::CopyToReg)
@@ -1814,12 +1814,12 @@ static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
if (!Visited.insert(Use).second)
return false;
- for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {
+ for (const SDValue &Op : Use->op_values()) {
// Ignore chain uses, they are validated by HandleMergeInputChains.
- if (Use->getOperand(i).getValueType() == MVT::Other && IgnoreChains)
+ if (Op.getValueType() == MVT::Other && IgnoreChains)
continue;
- SDNode *N = Use->getOperand(i).getNode();
+ SDNode *N = Op.getNode();
if (N == Def) {
if (Use == ImmedUse || Use == Root)
continue; // We are not looking for immediate use.
@@ -2212,10 +2212,10 @@ HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched,
// If we have a token factor, we want to add all inputs of the token factor
// that are not part of the pattern we're matching.
- for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) {
+ for (const SDValue &Op : N->op_values()) {
if (!std::count(ChainNodesMatched.begin(), ChainNodesMatched.end(),
- N->getOperand(op).getNode()))
- InputChains.push_back(N->getOperand(op));
+ Op.getNode()))
+ InputChains.push_back(Op);
}
}
@@ -2542,7 +2542,7 @@ public:
J.setNode(E);
}
};
-} // namespace
+}
SDNode *SelectionDAGISel::
SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
@@ -2562,6 +2562,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
case ISD::TargetConstantPool:
case ISD::TargetFrameIndex:
case ISD::TargetExternalSymbol:
+ case ISD::MCSymbol:
case ISD::TargetBlockAddress:
case ISD::TargetJumpTable:
case ISD::TargetGlobalTLSAddress:
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
index 19b5d16..4df5ede 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
@@ -132,7 +132,7 @@ namespace llvm {
"color=blue,style=dashed");
}
};
-} // namespace llvm
+}
std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
const SelectionDAG *G) {
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index a6b3fc6..bd40cac 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -289,7 +289,7 @@ lowerCallFromStatepoint(ImmutableStatepoint ISP, MachineBasicBlock *LandingPad,
ImmutableCallSite CS(ISP.getCallSite());
- SDValue ActualCallee = Builder.getValue(ISP.getActualCallee());
+ SDValue ActualCallee = Builder.getValue(ISP.getCalledValue());
assert(CS.getCallingConv() != CallingConv::AnyReg &&
"anyregcc is not supported on statepoints!");
@@ -815,8 +815,8 @@ void SelectionDAGBuilder::visitGCResult(const CallInst &CI) {
// register because statepoint and actuall call return types can be
// different, and getValue() will use CopyFromReg of the wrong type,
// which is always i32 in our case.
- PointerType *CalleeType =
- cast<PointerType>(ImmutableStatepoint(I).getActualCallee()->getType());
+ PointerType *CalleeType = cast<PointerType>(
+ ImmutableStatepoint(I).getCalledValue()->getType());
Type *RetTy =
cast<FunctionType>(CalleeType->getElementType())->getReturnType();
SDValue CopyFromReg = getCopyFromRegs(I, RetTy);
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index c70c3a2..e7722b3 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -700,6 +700,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
if (ShAmt >= BitWidth)
break;
+ APInt InDemandedMask = (NewMask << ShAmt);
+
+ // If the shift is exact, then it does demand the low bits (and knows that
+ // they are zero).
+ if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
+ InDemandedMask |= APInt::getLowBitsSet(BitWidth, ShAmt);
+
// If this is ((X << C1) >>u ShAmt), see if we can simplify this into a
// single shift. We can do this if the top bits (which are shifted out)
// are never demanded.
@@ -722,7 +729,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
}
// Compute the new bits that are at the top now.
- if (SimplifyDemandedBits(InOp, (NewMask << ShAmt),
+ if (SimplifyDemandedBits(InOp, InDemandedMask,
KnownZero, KnownOne, TLO, Depth+1))
return true;
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
@@ -753,6 +760,11 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
APInt InDemandedMask = (NewMask << ShAmt);
+ // If the shift is exact, then it does demand the low bits (and knows that
+ // they are zero).
+ if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
+ InDemandedMask |= APInt::getLowBitsSet(BitWidth, ShAmt);
+
// If any of the demanded bits are produced by the sign extension, we also
// demand the input sign bit.
APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
@@ -771,10 +783,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
// If the input sign bit is known to be zero, or if none of the top bits
// are demanded, turn this into an unsigned shift right.
- if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits)
- return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT,
- Op.getOperand(0),
- Op.getOperand(1)));
+ if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) {
+ SDNodeFlags Flags;
+ Flags.setExact(cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact());
+ return TLO.CombineTo(Op,
+ TLO.DAG.getNode(ISD::SRL, dl, VT, Op.getOperand(0),
+ Op.getOperand(1), &Flags));
+ }
int Log2 = NewMask.exactLogBase2();
if (Log2 >= 0) {
@@ -2659,10 +2674,9 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
/// \brief Given an exact SDIV by a constant, create a multiplication
/// with the multiplicative inverse of the constant.
-SDValue TargetLowering::BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl,
- SelectionDAG &DAG) const {
- ConstantSDNode *C = cast<ConstantSDNode>(Op2);
- APInt d = C->getAPIntValue();
+static SDValue BuildExactSDIV(const TargetLowering &TLI, SDValue Op1, APInt d,
+ SDLoc dl, SelectionDAG &DAG,
+ std::vector<SDNode *> &Created) {
assert(d != 0 && "Division by zero!");
// Shift the value upfront if it is even, so the LSB is one.
@@ -2670,10 +2684,11 @@ SDValue TargetLowering::BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl,
if (ShAmt) {
// TODO: For UDIV use SRL instead of SRA.
SDValue Amt =
- DAG.getConstant(ShAmt, dl, getShiftAmountTy(Op1.getValueType()));
+ DAG.getConstant(ShAmt, dl, TLI.getShiftAmountTy(Op1.getValueType()));
SDNodeFlags Flags;
Flags.setExact(true);
Op1 = DAG.getNode(ISD::SRA, dl, Op1.getValueType(), Op1, Amt, &Flags);
+ Created.push_back(Op1.getNode());
d = d.ashr(ShAmt);
}
@@ -2682,8 +2697,10 @@ SDValue TargetLowering::BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl,
while ((t = d*xn) != 1)
xn *= APInt(d.getBitWidth(), 2) - t;
- Op2 = DAG.getConstant(xn, dl, Op1.getValueType());
- return DAG.getNode(ISD::MUL, dl, Op1.getValueType(), Op1, Op2);
+ SDValue Op2 = DAG.getConstant(xn, dl, Op1.getValueType());
+ SDValue Mul = DAG.getNode(ISD::MUL, dl, Op1.getValueType(), Op1, Op2);
+ Created.push_back(Mul.getNode());
+ return Mul;
}
/// \brief Given an ISD::SDIV node expressing a divide by constant,
@@ -2703,6 +2720,10 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, const APInt &Divisor,
if (!isTypeLegal(VT))
return SDValue();
+ // If the sdiv has an 'exact' bit we can use a simpler lowering.
+ if (cast<BinaryWithFlagsSDNode>(N)->Flags.hasExact())
+ return BuildExactSDIV(*this, N->getOperand(0), Divisor, dl, DAG, *Created);
+
APInt::ms magics = Divisor.magic();
// Multiply the numerator (operand 0) by the magic value
diff --git a/contrib/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/contrib/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
index d60e5f9..e7b2a8e 100644
--- a/contrib/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
+++ b/contrib/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
@@ -59,7 +59,7 @@ private:
Type *Ty, Value *BasePtr, int Idx1, int Idx2,
const char *Name);
};
-} // namespace
+}
INITIALIZE_PASS_BEGIN(ShadowStackGCLowering, "shadow-stack-gc-lowering",
"Shadow Stack GC Lowering", false, false)
@@ -189,7 +189,7 @@ public:
}
}
};
-} // namespace
+}
Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
diff --git a/contrib/llvm/lib/CodeGen/Spiller.h b/contrib/llvm/lib/CodeGen/Spiller.h
index b1019c1..08f99ec 100644
--- a/contrib/llvm/lib/CodeGen/Spiller.h
+++ b/contrib/llvm/lib/CodeGen/Spiller.h
@@ -37,6 +37,6 @@ namespace llvm {
MachineFunction &mf,
VirtRegMap &vrm);
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/SplitKit.h b/contrib/llvm/lib/CodeGen/SplitKit.h
index 4eaf03e..69c65ff 100644
--- a/contrib/llvm/lib/CodeGen/SplitKit.h
+++ b/contrib/llvm/lib/CodeGen/SplitKit.h
@@ -39,7 +39,7 @@ class raw_ostream;
/// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting
/// opportunities.
-class SplitAnalysis {
+class LLVM_LIBRARY_VISIBILITY SplitAnalysis {
public:
const MachineFunction &MF;
const VirtRegMap &VRM;
@@ -208,7 +208,7 @@ public:
/// - Finish the current interval with closeIntv and repeat from 2.
/// - Rewrite instructions with finish().
///
-class SplitEditor {
+class LLVM_LIBRARY_VISIBILITY SplitEditor {
SplitAnalysis &SA;
LiveIntervals &LIS;
VirtRegMap &VRM;
@@ -466,6 +466,6 @@ public:
unsigned IntvOut, SlotIndex EnterAfter);
};
-} // namespace llvm
+}
#endif
diff --git a/contrib/llvm/lib/CodeGen/StatepointExampleGC.cpp b/contrib/llvm/lib/CodeGen/StatepointExampleGC.cpp
index b9523e5..95dfd75 100644
--- a/contrib/llvm/lib/CodeGen/StatepointExampleGC.cpp
+++ b/contrib/llvm/lib/CodeGen/StatepointExampleGC.cpp
@@ -45,7 +45,7 @@ public:
return (1 == PT->getAddressSpace());
}
};
-} // namespace
+}
static GCRegistry::Add<StatepointGC> X("statepoint-example",
"an example strategy for statepoint");
diff --git a/contrib/llvm/lib/CodeGen/TailDuplication.cpp b/contrib/llvm/lib/CodeGen/TailDuplication.cpp
index 164badd..237460c 100644
--- a/contrib/llvm/lib/CodeGen/TailDuplication.cpp
+++ b/contrib/llvm/lib/CodeGen/TailDuplication.cpp
@@ -125,7 +125,7 @@ namespace {
};
char TailDuplicatePass::ID = 0;
-} // namespace
+}
char &llvm::TailDuplicateID = TailDuplicatePass::ID;
@@ -627,11 +627,8 @@ TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) {
return false;
if (TailBB->pred_empty())
return false;
- MachineBasicBlock::iterator I = TailBB->begin();
- MachineBasicBlock::iterator E = TailBB->end();
- while (I != E && I->isDebugValue())
- ++I;
- if (I == E)
+ MachineBasicBlock::iterator I = TailBB->getFirstNonDebugInstr();
+ if (I == TailBB->end())
return true;
return I->isUnconditionalBranch();
}
diff --git a/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp b/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 1bc89aa..78492a6 100644
--- a/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/contrib/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -38,6 +38,11 @@
#include <cctype>
using namespace llvm;
+static cl::opt<bool> JumpIsExpensiveOverride(
+ "jump-is-expensive", cl::init(false),
+ cl::desc("Do not create extra branches to split comparison logic."),
+ cl::Hidden);
+
/// InitLibcallNames - Set default libcall names.
///
static void InitLibcallNames(const char **Names, const Triple &TT) {
@@ -757,7 +762,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
IntDivIsCheap = false;
FsqrtIsCheap = false;
Pow2SDivIsCheap = false;
- JumpIsExpensive = false;
+ JumpIsExpensive = JumpIsExpensiveOverride;
PredictableSelectIsExpensive = false;
MaskAndBranchFoldingIsLegal = false;
EnableExtLdPromotion = false;
@@ -778,7 +783,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
InsertFencesForAtomic = false;
MinimumJumpTableEntries = 4;
- InitLibcallNames(LibcallRoutineNames, Triple(TM.getTargetTriple()));
+ InitLibcallNames(LibcallRoutineNames, TM.getTargetTriple());
InitCmpLibcallCCs(CmpLibcallCCs);
InitLibcallCallingConvs(LibcallCallingConvs);
}
@@ -915,6 +920,12 @@ bool TargetLoweringBase::canOpTrap(unsigned Op, EVT VT) const {
}
}
+void TargetLoweringBase::setJumpIsExpensive(bool isExpensive) {
+ // If the command-line option was specified, ignore this request.
+ if (!JumpIsExpensiveOverride.getNumOccurrences())
+ JumpIsExpensive = isExpensive;
+}
+
TargetLoweringBase::LegalizeKind
TargetLoweringBase::getTypeConversion(LLVMContext &Context, EVT VT) const {
// If this is a simple type, use the ComputeRegisterProp mechanism.
diff --git a/contrib/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/contrib/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index d7b043d..2f78763 100644
--- a/contrib/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/contrib/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -440,16 +440,6 @@ TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO()
SupportIndirectSymViaGOTPCRel = true;
}
-/// getDepLibFromLinkerOpt - Extract the dependent library name from a linker
-/// option string. Returns StringRef() if the option does not specify a library.
-StringRef TargetLoweringObjectFileMachO::
-getDepLibFromLinkerOpt(StringRef LinkerOption) const {
- const char *LibCmd = "-l";
- if (LinkerOption.startswith(LibCmd))
- return LinkerOption.substr(strlen(LibCmd));
- return StringRef();
-}
-
/// emitModuleFlags - Perform code emission for module flags.
void TargetLoweringObjectFileMachO::
emitModuleFlags(MCStreamer &Streamer,
@@ -850,8 +840,6 @@ static int getSelectionForCOFF(const GlobalValue *GV) {
} else {
return COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
}
- } else if (GV->isWeakForLinker()) {
- return COFF::IMAGE_COMDAT_SELECT_ANY;
}
return 0;
}
@@ -990,14 +978,6 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
}
-StringRef TargetLoweringObjectFileCOFF::
-getDepLibFromLinkerOpt(StringRef LinkerOption) const {
- const char *LibCmd = "/DEFAULTLIB:";
- if (LinkerOption.startswith(LibCmd))
- return LinkerOption.substr(strlen(LibCmd));
- return StringRef();
-}
-
void TargetLoweringObjectFileCOFF::
emitModuleFlags(MCStreamer &Streamer,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
@@ -1045,3 +1025,36 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
return getContext().getAssociativeCOFFSection(
cast<MCSectionCOFF>(StaticDtorSection), KeySym);
}
+
+void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
+ raw_ostream &OS, const GlobalValue *GV, const Mangler &Mang) const {
+ if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
+ return;
+
+ const Triple &TT = getTargetTriple();
+
+ if (TT.isKnownWindowsMSVCEnvironment())
+ OS << " /EXPORT:";
+ else
+ OS << " -export:";
+
+ if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
+ std::string Flag;
+ raw_string_ostream FlagOS(Flag);
+ Mang.getNameWithPrefix(FlagOS, GV, false);
+ FlagOS.flush();
+ if (Flag[0] == DL->getGlobalPrefix())
+ OS << Flag.substr(1);
+ else
+ OS << Flag;
+ } else {
+ Mang.getNameWithPrefix(OS, GV, false);
+ }
+
+ if (!GV->getValueType()->isFunctionTy()) {
+ if (TT.isKnownWindowsMSVCEnvironment())
+ OS << ",DATA";
+ else
+ OS << ",data";
+ }
+}
diff --git a/contrib/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/contrib/llvm/lib/CodeGen/TargetOptionsImpl.cpp
index f4926cb..8d2048f 100644
--- a/contrib/llvm/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/contrib/llvm/lib/CodeGen/TargetOptionsImpl.cpp
@@ -47,10 +47,3 @@ bool TargetOptions::LessPreciseFPMAD() const {
bool TargetOptions::HonorSignDependentRoundingFPMath() const {
return !UnsafeFPMath && HonorSignDependentRoundingFPMathOption;
}
-
-/// getTrapFunctionName - If this returns a non-empty string, this means isel
-/// should lower Intrinsic::trap to a call to the specified function name
-/// instead of an ISD::TRAP node.
-StringRef TargetOptions::getTrapFunctionName() const {
- return TrapFuncName;
-}
diff --git a/contrib/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/contrib/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index 6bceccc..e84bea6 100644
--- a/contrib/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/contrib/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -1207,12 +1207,24 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
}
}
+ // If the instruction is convertible to 3 Addr, instead
+ // of returning try 3 Addr transformation aggresively and
+ // use this variable to check later. Because it might be better.
+ // For example, we can just use `leal (%rsi,%rdi), %eax` and `ret`
+ // instead of the following code.
+ // addl %esi, %edi
+ // movl %edi, %eax
+ // ret
+ bool commuted = false;
+
// If it's profitable to commute, try to do so.
if (TryCommute && commuteInstruction(mi, regB, regC, Dist)) {
+ commuted = true;
++NumCommuted;
if (AggressiveCommute)
++NumAggrCommuted;
- return false;
+ if (!MI.isConvertibleTo3Addr())
+ return false;
}
if (shouldOnlyCommute)
@@ -1220,7 +1232,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
// If there is one more use of regB later in the same MBB, consider
// re-schedule this MI below it.
- if (EnableRescheduling && rescheduleMIBelowKill(mi, nmi, regB)) {
+ if (!commuted && EnableRescheduling && rescheduleMIBelowKill(mi, nmi, regB)) {
++NumReSchedDowns;
return true;
}
@@ -1237,6 +1249,10 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
}
}
+ // Return if it is commuted but 3 addr conversion is failed.
+ if (commuted)
+ return false;
+
// If there is one more use of regB later in the same MBB, consider
// re-schedule it before this MI if it's legal.
if (EnableRescheduling && rescheduleKillAboveMI(mi, nmi, regB)) {
diff --git a/contrib/llvm/lib/CodeGen/UnreachableBlockElim.cpp b/contrib/llvm/lib/CodeGen/UnreachableBlockElim.cpp
index 5c54cdb..d393e10 100644
--- a/contrib/llvm/lib/CodeGen/UnreachableBlockElim.cpp
+++ b/contrib/llvm/lib/CodeGen/UnreachableBlockElim.cpp
@@ -51,7 +51,7 @@ namespace {
AU.addPreserved<DominatorTreeWrapperPass>();
}
};
-} // namespace
+}
char UnreachableBlockElim::ID = 0;
INITIALIZE_PASS(UnreachableBlockElim, "unreachableblockelim",
"Remove unreachable blocks from the CFG", false, false)
diff --git a/contrib/llvm/lib/CodeGen/WinEHPrepare.cpp b/contrib/llvm/lib/CodeGen/WinEHPrepare.cpp
index 8c932cf..dbc0d91 100644
--- a/contrib/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/contrib/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -76,7 +76,7 @@ public:
WinEHPrepare(const TargetMachine *TM = nullptr)
: FunctionPass(ID) {
if (TM)
- TheTriple = Triple(TM->getTargetTriple());
+ TheTriple = TM->getTargetTriple();
}
bool runOnFunction(Function &Fn) override;
@@ -106,8 +106,8 @@ private:
LandingPadInst *OutlinedLPad,
const LandingPadInst *OriginalLPad,
FrameVarInfoMap &VarInfo);
- Function *createHandlerFunc(Type *RetTy, const Twine &Name, Module *M,
- Value *&ParentFP);
+ Function *createHandlerFunc(Function *ParentFn, Type *RetTy,
+ const Twine &Name, Module *M, Value *&ParentFP);
bool outlineHandler(ActionHandler *Action, Function *SrcFn,
LandingPadInst *LPad, BasicBlock *StartBB,
FrameVarInfoMap &VarInfo);
@@ -1329,14 +1329,15 @@ void WinEHPrepare::addStubInvokeToHandlerIfNeeded(Function *Handler) {
// FIXME: Consider sinking this into lib/Target/X86 somehow. TargetLowering
// usually doesn't build LLVM IR, so that's probably the wrong place.
-Function *WinEHPrepare::createHandlerFunc(Type *RetTy, const Twine &Name,
- Module *M, Value *&ParentFP) {
+Function *WinEHPrepare::createHandlerFunc(Function *ParentFn, Type *RetTy,
+ const Twine &Name, Module *M,
+ Value *&ParentFP) {
// x64 uses a two-argument prototype where the parent FP is the second
// argument. x86 uses no arguments, just the incoming EBP value.
LLVMContext &Context = M->getContext();
+ Type *Int8PtrType = Type::getInt8PtrTy(Context);
FunctionType *FnType;
if (TheTriple.getArch() == Triple::x86_64) {
- Type *Int8PtrType = Type::getInt8PtrTy(Context);
Type *ArgTys[2] = {Int8PtrType, Int8PtrType};
FnType = FunctionType::get(RetTy, ArgTys, false);
} else {
@@ -1353,9 +1354,13 @@ Function *WinEHPrepare::createHandlerFunc(Type *RetTy, const Twine &Name,
assert(M);
Function *FrameAddressFn =
Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
- Value *Args[1] = {ConstantInt::get(Type::getInt32Ty(Context), 1)};
- ParentFP = CallInst::Create(FrameAddressFn, Args, "parent_fp",
- &Handler->getEntryBlock());
+ Function *RecoverFPFn =
+ Intrinsic::getDeclaration(M, Intrinsic::x86_seh_recoverfp);
+ IRBuilder<> Builder(&Handler->getEntryBlock());
+ Value *EBP =
+ Builder.CreateCall(FrameAddressFn, {Builder.getInt32(1)}, "ebp");
+ Value *ParentI8Fn = Builder.CreateBitCast(ParentFn, Int8PtrType);
+ ParentFP = Builder.CreateCall(RecoverFPFn, {ParentI8Fn, EBP});
}
return Handler;
}
@@ -1371,10 +1376,10 @@ bool WinEHPrepare::outlineHandler(ActionHandler *Action, Function *SrcFn,
Value *ParentFP;
Function *Handler;
if (Action->getType() == Catch) {
- Handler = createHandlerFunc(Int8PtrType, SrcFn->getName() + ".catch", M,
+ Handler = createHandlerFunc(SrcFn, Int8PtrType, SrcFn->getName() + ".catch", M,
ParentFP);
} else {
- Handler = createHandlerFunc(Type::getVoidTy(Context),
+ Handler = createHandlerFunc(SrcFn, Type::getVoidTy(Context),
SrcFn->getName() + ".cleanup", M, ParentFP);
}
Handler->setPersonalityFn(SrcFn->getPersonalityFn());
@@ -2395,40 +2400,43 @@ void WinEHPrepare::findCleanupHandlers(LandingPadActions &Actions,
MaybeCall = MaybeCall->getNextNode();
}
- // Look for outlined finally calls.
- if (CallSite FinallyCall = matchOutlinedFinallyCall(BB, MaybeCall)) {
- Function *Fin = FinallyCall.getCalledFunction();
- assert(Fin && "outlined finally call should be direct");
- auto *Action = new CleanupHandler(BB);
- Action->setHandlerBlockOrFunc(Fin);
- Actions.insertCleanupHandler(Action);
- CleanupHandlerMap[BB] = Action;
- DEBUG(dbgs() << " Found frontend-outlined finally call to "
- << Fin->getName() << " in block "
- << Action->getStartBlock()->getName() << "\n");
-
- // Split the block if there were more interesting instructions and look
- // for finally calls in the normal successor block.
- BasicBlock *SuccBB = BB;
- if (FinallyCall.getInstruction() != BB->getTerminator() &&
- FinallyCall.getInstruction()->getNextNode() !=
- BB->getTerminator()) {
- SuccBB =
- SplitBlock(BB, FinallyCall.getInstruction()->getNextNode(), DT);
- } else {
- if (FinallyCall.isInvoke()) {
+ // Look for outlined finally calls on x64, since those happen to match the
+ // prototype provided by the runtime.
+ if (TheTriple.getArch() == Triple::x86_64) {
+ if (CallSite FinallyCall = matchOutlinedFinallyCall(BB, MaybeCall)) {
+ Function *Fin = FinallyCall.getCalledFunction();
+ assert(Fin && "outlined finally call should be direct");
+ auto *Action = new CleanupHandler(BB);
+ Action->setHandlerBlockOrFunc(Fin);
+ Actions.insertCleanupHandler(Action);
+ CleanupHandlerMap[BB] = Action;
+ DEBUG(dbgs() << " Found frontend-outlined finally call to "
+ << Fin->getName() << " in block "
+ << Action->getStartBlock()->getName() << "\n");
+
+ // Split the block if there were more interesting instructions and
+ // look for finally calls in the normal successor block.
+ BasicBlock *SuccBB = BB;
+ if (FinallyCall.getInstruction() != BB->getTerminator() &&
+ FinallyCall.getInstruction()->getNextNode() !=
+ BB->getTerminator()) {
SuccBB =
- cast<InvokeInst>(FinallyCall.getInstruction())->getNormalDest();
+ SplitBlock(BB, FinallyCall.getInstruction()->getNextNode(), DT);
} else {
- SuccBB = BB->getUniqueSuccessor();
- assert(SuccBB &&
- "splitOutlinedFinallyCalls didn't insert a branch");
+ if (FinallyCall.isInvoke()) {
+ SuccBB = cast<InvokeInst>(FinallyCall.getInstruction())
+ ->getNormalDest();
+ } else {
+ SuccBB = BB->getUniqueSuccessor();
+ assert(SuccBB &&
+ "splitOutlinedFinallyCalls didn't insert a branch");
+ }
}
+ BB = SuccBB;
+ if (BB == EndBB)
+ return;
+ continue;
}
- BB = SuccBB;
- if (BB == EndBB)
- return;
- continue;
}
}
@@ -2518,7 +2526,7 @@ struct WinEHNumbering {
void calculateStateNumbers(const Function &F);
void findActionRootLPads(const Function &F);
};
-} // namespace
+}
void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) {
WinEHUnwindMapEntry UME;
OpenPOWER on IntegriCloud