From 617f84ddbd2e5c5b8c0504d923b6c4e539c35b9b Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 28 Feb 2012 23:53:30 +0000 Subject: [PATCH] ARM implement TargetInstrInfo::getNoopForMachoTarget() Without this hook, functions w/ a completely empty body (including no epilogue) will cause an MCEmitter assertion failure. For example, define internal fastcc void @empty_function() { unreachable } rdar://10947471 llvm-svn: 151673 --- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 4 ++++ llvm/lib/Target/ARM/ARMBaseInstrInfo.h | 3 +++ llvm/lib/Target/ARM/ARMInstrInfo.cpp | 17 +++++++++++++++++ llvm/lib/Target/ARM/ARMInstrInfo.h | 3 +++ llvm/lib/Target/ARM/Thumb1InstrInfo.cpp | 11 ++++++++++- llvm/lib/Target/ARM/Thumb1InstrInfo.h | 3 +++ llvm/lib/Target/ARM/Thumb2InstrInfo.cpp | 8 ++++++++ llvm/lib/Target/ARM/Thumb2InstrInfo.h | 3 +++ llvm/test/MC/MachO/ARM/empty-function-nop.ll | 15 +++++++++++++++ 9 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/MachO/ARM/empty-function-nop.ll diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index ea4baab95c50..8fb04276f1c4 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3003,3 +3003,7 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { // This will go before any implicit ops. AddDefaultPred(MachineInstrBuilder(MI).addOperand(MI->getOperand(1))); } + +bool ARMBaseInstrInfo::hasNOP() const { + return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0; +} diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index 8899c9a8331f..314e3177bec2 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -35,6 +35,9 @@ protected: explicit ARMBaseInstrInfo(const ARMSubtarget &STI); public: + // Return whether the target has an explicit NOP encoding. + bool hasNOP() const; + // Return the non-pre/post incrementing version of 'Opc'. Return 0 // if there is not such an opcode. virtual unsigned getUnindexedOpcode(unsigned Opc) const =0; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.cpp b/llvm/lib/Target/ARM/ARMInstrInfo.cpp index e4d46d19ef5a..b8f607eb4c55 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMInstrInfo.cpp @@ -21,12 +21,29 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInst.h" using namespace llvm; ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) : ARMBaseInstrInfo(STI), RI(*this, STI) { } +/// getNoopForMachoTarget - Return the noop instruction to use for a noop. +void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { + if (hasNOP()) { + NopInst.setOpcode(ARM::NOP); + NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + NopInst.addOperand(MCOperand::CreateReg(0)); + } else { + NopInst.setOpcode(ARM::MOVr); + NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); + NopInst.addOperand(MCOperand::CreateReg(ARM::R0)); + NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + NopInst.addOperand(MCOperand::CreateReg(0)); + NopInst.addOperand(MCOperand::CreateReg(0)); + } +} + unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { switch (Opc) { default: break; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.h b/llvm/lib/Target/ARM/ARMInstrInfo.h index 3a69692326d9..7bedf30cbe35 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMInstrInfo.h @@ -28,6 +28,9 @@ class ARMInstrInfo : public ARMBaseInstrInfo { public: explicit ARMInstrInfo(const ARMSubtarget &STI); + /// getNoopForMachoTarget - Return the noop instruction to use for a noop. + void getNoopForMachoTarget(MCInst &NopInst) const; + // Return the non-pre/post incrementing version of 'Opc'. Return 0 // if there is not such an opcode. unsigned getUnindexedOpcode(unsigned Opc) const; diff --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp index ba16db34bd05..adaccddf8749 100644 --- a/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp +++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp @@ -19,7 +19,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/ADT/SmallVector.h" -#include "Thumb1InstrInfo.h" +#include "llvm/MC/MCInst.h" using namespace llvm; @@ -27,6 +27,15 @@ Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI) : ARMBaseInstrInfo(STI), RI(*this, STI) { } +/// getNoopForMachoTarget - Return the noop instruction to use for a noop. +void Thumb1InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { + NopInst.setOpcode(ARM::tMOVr); + NopInst.addOperand(MCOperand::CreateReg(ARM::R8)); + NopInst.addOperand(MCOperand::CreateReg(ARM::R8)); + NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + NopInst.addOperand(MCOperand::CreateReg(0)); +} + unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const { return 0; } diff --git a/llvm/lib/Target/ARM/Thumb1InstrInfo.h b/llvm/lib/Target/ARM/Thumb1InstrInfo.h index 4479101f2e6c..4d97626925d1 100644 --- a/llvm/lib/Target/ARM/Thumb1InstrInfo.h +++ b/llvm/lib/Target/ARM/Thumb1InstrInfo.h @@ -27,6 +27,9 @@ class Thumb1InstrInfo : public ARMBaseInstrInfo { public: explicit Thumb1InstrInfo(const ARMSubtarget &STI); + /// getNoopForMachoTarget - Return the noop instruction to use for a noop. + void getNoopForMachoTarget(MCInst &NopInst) const; + // Return the non-pre/post incrementing version of 'Opc'. Return 0 // if there is not such an opcode. unsigned getUnindexedOpcode(unsigned Opc) const; diff --git a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp index 8a6276be5147..6cb182a08491 100644 --- a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp +++ b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCInst.h" #include "llvm/Support/CommandLine.h" using namespace llvm; @@ -34,6 +35,13 @@ Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI) : ARMBaseInstrInfo(STI), RI(*this, STI) { } +/// getNoopForMachoTarget - Return the noop instruction to use for a noop. +void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { + NopInst.setOpcode(ARM::tNOP); + NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + NopInst.addOperand(MCOperand::CreateReg(0)); +} + unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const { // FIXME return 0; diff --git a/llvm/lib/Target/ARM/Thumb2InstrInfo.h b/llvm/lib/Target/ARM/Thumb2InstrInfo.h index 447949c7be32..a754649b7f6c 100644 --- a/llvm/lib/Target/ARM/Thumb2InstrInfo.h +++ b/llvm/lib/Target/ARM/Thumb2InstrInfo.h @@ -28,6 +28,9 @@ class Thumb2InstrInfo : public ARMBaseInstrInfo { public: explicit Thumb2InstrInfo(const ARMSubtarget &STI); + /// getNoopForMachoTarget - Return the noop instruction to use for a noop. + void getNoopForMachoTarget(MCInst &NopInst) const; + // Return the non-pre/post incrementing version of 'Opc'. Return 0 // if there is not such an opcode. unsigned getUnindexedOpcode(unsigned Opc) const; diff --git a/llvm/test/MC/MachO/ARM/empty-function-nop.ll b/llvm/test/MC/MachO/ARM/empty-function-nop.ll new file mode 100644 index 000000000000..3ac4d82afa32 --- /dev/null +++ b/llvm/test/MC/MachO/ARM/empty-function-nop.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -filetype=obj -mtriple=thumbv6-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=T1 +; RUN: llc < %s -filetype=obj -mtriple=thumbv7-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=T2 +; RUN: llc < %s -filetype=obj -mtriple=armv6-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=ARM +; RUN: llc < %s -filetype=obj -mtriple=armv7-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=ARMV7 + +; Empty functions need a NOP in them for MachO to prevent DWARF FDEs from +; getting all mucked up. See lib/CodeGen/AsmPrinter/AsmPrinter.cpp for +; details. +define internal fastcc void @empty_function() { + unreachable +} +; CHECK-T1: ('_section_data', 'c046') +; CHECK-T2: ('_section_data', '00bf') +; CHECK-ARM: ('_section_data', '0000a0e1') +; CHECK-ARMV7: ('_section_data', '00f020e3')