diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index c5f8b906ab9c0a..ab10a3afb58d34 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -81,6 +81,11 @@ cl::opt NMipsGuardKCFIPrefetch("nmips-guard-kcfi-prefetch", cl::desc("On NanoMips, guard KCFI signatures against branch prefetch"), cl::init(true)); +static cl::opt DisableNanoMipsBalcStubs( + "disable-nanomips-balc-stubs", cl::Hidden, + cl::desc("NANOMIPS: Disable balc stubs optimization in the linker"), + cl::init(false)); + void MipsAsmPrinter::emitJumpTableInfo() { if (!Subtarget->hasNanoMips() || Subtarget->useAbsoluteJumpTables() ) { AsmPrinter::emitJumpTableInfo(); @@ -475,6 +480,18 @@ void MipsAsmPrinter::emitLoadAddressNM(MCStreamer &OutStreamer, LA.addOperand(Addr); EmitToStreamer(OutStreamer, LA); } +// NOTE: This is being used to control optimization of BALC in the linker. +static void emitDirectivesToDisableBalcStubs(const MachineInstr &MI, + MCContext &OutContext, + TargetMachine &TM, + MCStreamer &OutStreamer) { + assert(DisableNanoMipsBalcStubs || !MI.getMF()->getFunction().hasOptSize()); + MCSymbol *OffsetLabel = OutContext.createTempSymbol(); + const MCExpr *OffsetExpr = MCSymbolRefExpr::create(OffsetLabel, OutContext); + OutStreamer.emitRelocDirective(*OffsetExpr, "R_NANOMIPS_NOTRAMP", nullptr, + SMLoc(), *TM.getMCSubtargetInfo()); + OutStreamer.emitLabel(OffsetLabel); +} void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) { // FIXME: Enable feature predicate checks once all the test pass. @@ -597,6 +614,11 @@ void MipsAsmPrinter::emitInstruction(const MachineInstr *MI) { continue; } + if (Subtarget->hasNanoMips() && I->getOpcode() == Mips::BALC_NM && + (!I->getMF()->getFunction().hasOptSize() || DisableNanoMipsBalcStubs)) { + emitDirectivesToDisableBalcStubs(*I, OutContext, TM, *OutStreamer); + } + // The inMips16Mode() test is not permanent. // Some instructions are marked as pseudo right now which // would make the test fail for the wrong reason but diff --git a/llvm/test/CodeGen/Mips/nanomips/disable-balc-stubs.ll b/llvm/test/CodeGen/Mips/nanomips/disable-balc-stubs.ll new file mode 100644 index 00000000000000..73e8564bbbbc3e --- /dev/null +++ b/llvm/test/CodeGen/Mips/nanomips/disable-balc-stubs.ll @@ -0,0 +1,39 @@ +; Should enable REQUIRES: nanomips +; ModuleID = 'disable-balc-stubs.c' +source_filename = "disable-balc-stubs.c" +target datalayout = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128" +target triple = "nanomips" + +; RUN: llc %s -o - | FileCheck %s +; RUN: llc %s --disable-nanomips-balc-stubs -o - | FileCheck %s --check-prefix=CHECK-DISABLED + + +; Function Attrs: noinline nounwind optnone +define dso_local void @y() #0 { +entry: + ret void +} + +; Function Attrs: noinline nounwind optsize +; CHECK: f: +; CHECK-DISABLED: f: +define dso_local void @f() #1 { +entry: + ; CHECK-NOT: R_NANOMIPS_NOTRAMP + ; CHECK-DISABLED: R_NANOMIPS_NOTRAMP + call void @y() + ret void +} + +; Function Attrs: noinline nounwind optnone +; CHECK: g: +; CHECK-DISABLED: g: +define dso_local void @g() #0 { +entry: + ; CHECK: R_NANOMIPS_NOTRAMP + call void @y() + ret void +} + +attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="i7200" "target-features"="+i7200,+pcrel,+relax,+soft-float,-noabicalls" "use-soft-float"="true" } +attributes #1 = { noinline nounwind optsize "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="i7200" "target-features"="+i7200,+pcrel,+relax,+soft-float,-noabicalls" "use-soft-float"="true" }