diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCAsmBackend.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h | 5 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 8 |
8 files changed, 49 insertions, 8 deletions
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp index c4e5051..cf3b3ae 100644 --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -115,3 +115,14 @@ bool MCAsmBackend::fixupNeedsRelaxationAdvanced( return true; return fixupNeedsRelaxation(Fixup, Value, DF, Layout); } + +bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const { + if (Sym && Sym->isMachO()) { + StringRef name = Sym->getName(); + // XXX: We intentionally leave out "___gcc_personality_v0" because, despite + // being system-defined like these two, it is not very commonly-used. + // Reserving an empty slot for it seems silly. + return name == "___gxx_personality_v0" || name == "___objc_personality_v0"; + } + return false; +} diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index f84aa4a..80d593b 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -922,6 +922,12 @@ EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const { return TargetOptions->EmitDwarfUnwind; } +bool MCContext::emitCompactUnwindNonCanonical() const { + if (TargetOptions) + return TargetOptions->EmitCompactUnwindNonCanonical; + return false; +} + void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) { // MCDwarf needs the root file as well as the compilation directory. // If we find a '.file 0' directive that will supersede these values. diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 0cb0459..c0e9f42 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -126,7 +126,7 @@ void MCStreamer::emitExplicitComments() {} void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) { for (auto &FI : DwarfFrameInfos) FI.CompactUnwindEncoding = - (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0); + (MAB ? MAB->generateCompactUnwindEncoding(&FI, &Context) : 0); } /// EmitIntValue - Special case of EmitValue that avoids the client having to diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp index 0667ca5..8a4923e 100644 --- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp +++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp @@ -39,6 +39,7 @@ MCOPT(bool, IncrementalLinkerCompatible) MCOPT(int, DwarfVersion) MCOPT(bool, Dwarf64) MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind) +MCOPT(bool, EmitCompactUnwindNonCanonical) MCOPT(bool, ShowMCInst) MCOPT(bool, FatalWarnings) MCOPT(bool, NoWarn) @@ -87,6 +88,14 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() { "Use target platform default"))); MCBINDOPT(EmitDwarfUnwind); + static cl::opt<bool> EmitCompactUnwindNonCanonical( + "emit-compact-unwind-non-canonical", + cl::desc( + "Whether to try to emit Compact Unwind for non canonical entries."), + cl::init( + false)); // By default, use DWARF for non-canonical personalities. + MCBINDOPT(EmitCompactUnwindNonCanonical); + static cl::opt<bool> ShowMCInst( "asm-show-inst", cl::desc("Emit internal instruction representation to assembly file")); @@ -135,6 +144,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() { Options.MCNoDeprecatedWarn = getNoDeprecatedWarn(); Options.MCNoTypeCheck = getNoTypeCheck(); Options.EmitDwarfUnwind = getEmitDwarfUnwind(); + Options.EmitCompactUnwindNonCanonical = getEmitCompactUnwindNonCanonical(); Options.AsSecureLogFile = getAsSecureLogFile(); return Options; diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 2089a24..7f20d73 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -564,10 +564,14 @@ public: } /// Generate the compact unwind encoding from the CFI directives. - uint32_t generateCompactUnwindEncoding( - ArrayRef<MCCFIInstruction> Instrs) const override { + uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const override { + ArrayRef<MCCFIInstruction> Instrs = FI->Instructions; if (Instrs.empty()) return CU::UNWIND_ARM64_MODE_FRAMELESS; + if (!isDarwinCanonicalPersonality(FI->Personality) && + !Ctxt->emitCompactUnwindNonCanonical()) + return CU::UNWIND_ARM64_MODE_DWARF; bool HasFP = false; unsigned StackSize = 0; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index df142b8..ea13634 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -1107,14 +1107,19 @@ enum CompactUnwindEncodings { /// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which /// tells the runtime to fallback and unwind using dwarf. uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding( - ArrayRef<MCCFIInstruction> Instrs) const { + const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const { DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n"); // Only armv7k uses CFI based unwinding. if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K) return 0; // No .cfi directives means no frame. + ArrayRef<MCCFIInstruction> Instrs = FI->Instructions; if (Instrs.empty()) return 0; + if (!isDarwinCanonicalPersonality(FI->Personality) && + !Ctxt->emitCompactUnwindNonCanonical()) + return CU::UNWIND_ARM_MODE_DWARF; + // Start off assuming CFA is at SP+0. unsigned CFARegister = ARM::SP; int CFARegisterOffset = 0; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h index 85013b5..ace573c 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -11,6 +11,7 @@ #include "ARMAsmBackend.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectWriter.h" namespace llvm { @@ -32,8 +33,8 @@ public: /*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype); } - uint32_t generateCompactUnwindEncoding( - ArrayRef<MCCFIInstruction> Instrs) const override; + uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 92344d4..8380f00 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -1327,9 +1327,13 @@ public: /// Implementation of algorithm to generate the compact unwind encoding /// for the CFI instructions. - uint32_t - generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const override { + uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const override { + ArrayRef<MCCFIInstruction> Instrs = FI->Instructions; if (Instrs.empty()) return 0; + if (!isDarwinCanonicalPersonality(FI->Personality) && + !Ctxt->emitCompactUnwindNonCanonical()) + return CU::UNWIND_MODE_DWARF; // Reset the saved registers. unsigned SavedRegIdx = 0; |