From 39fa84d07c7f20df31723a694e3ad3e012f52cad Mon Sep 17 00:00:00 2001 From: Mirko Brkusanin Date: Tue, 8 Oct 2019 14:32:03 +0000 Subject: [PATCH] [Mips] Emit proper ABI for _mcount calls When -pg option is present than a call to _mcount is inserted into every function. However since the proper ABI was not followed then the generated gmon.out did not give proper results. By inserting needed instructions before every _mcount we can fix this. Differential Revision: https://reviews.llvm.org/D68390 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374055 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 45 ++++++++++ lib/Target/Mips/MipsSEISelDAGToDAG.h | 4 + test/CodeGen/Mips/mcount.ll | 117 +++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 test/CodeGen/Mips/mcount.ll diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index d9354cadc73..65afb3650f8 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -124,6 +124,33 @@ bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, return true; } +void MipsSEDAGToDAGISel::emitMCountABI(MachineInstr &MI, MachineBasicBlock &MBB, + MachineFunction &MF) { + MachineInstrBuilder MIB(MF, &MI); + if (!Subtarget->isABI_O32()) { // N32, N64 + // Save current return address. + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Mips::OR)) + .addDef(Mips::AT_64) + .addUse(Mips::RA_64) + .addUse(Mips::ZERO_64); + // Stops instruction above from being removed later on. + MIB.addUse(Mips::AT_64, RegState::Implicit); + } else { // O32 + // Save current return address. + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Mips::OR)) + .addDef(Mips::AT) + .addUse(Mips::RA) + .addUse(Mips::ZERO); + // _mcount pops 2 words from stack. + BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(Mips::ADDiu)) + .addDef(Mips::SP) + .addUse(Mips::SP) + .addImm(-8); + // Stops first instruction above from being removed later on. + MIB.addUse(Mips::AT, RegState::Implicit); + } +} + void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { MF.getInfo()->initGlobalBaseReg(); @@ -150,6 +177,24 @@ void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { if (Subtarget->isABI_FPXX() && !Subtarget->hasMTHC1()) MI.addOperand(MachineOperand::CreateReg(Mips::SP, false, true)); break; + case Mips::JAL: + case Mips::JAL_MM: + if (MI.getOperand(0).isGlobal() && + MI.getOperand(0).getGlobal()->getGlobalIdentifier() == "_mcount") + emitMCountABI(MI, MBB, MF); + break; + case Mips::JALRPseudo: + case Mips::JALR64Pseudo: + case Mips::JALR16_MM: + if (MI.getOperand(2).isMCSymbol() && + MI.getOperand(2).getMCSymbol()->getName() == "_mcount") + emitMCountABI(MI, MBB, MF); + break; + case Mips::JALR: + if (MI.getOperand(3).isMCSymbol() && + MI.getOperand(3).getMCSymbol()->getName() == "_mcount") + emitMCountABI(MI, MBB, MF); + break; default: replaceUsesWithZeroReg(MRI, MI); } diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.h b/lib/Target/Mips/MipsSEISelDAGToDAG.h index 80ab1ea9f63..39f665be571 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -128,6 +128,10 @@ private: bool trySelect(SDNode *Node) override; + // Emits proper ABI for _mcount profiling calls. + void emitMCountABI(MachineInstr &MI, MachineBasicBlock &MBB, + MachineFunction &MF); + void processFunctionAfterISel(MachineFunction &MF) override; bool SelectInlineAsmMemoryOperand(const SDValue &Op, diff --git a/test/CodeGen/Mips/mcount.ll b/test/CodeGen/Mips/mcount.ll new file mode 100644 index 00000000000..e136ae03da5 --- /dev/null +++ b/test/CodeGen/Mips/mcount.ll @@ -0,0 +1,117 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=MIPS32 +; RUN: llc -march=mips -relocation-model=pic < %s | FileCheck %s -check-prefix=MIPS32-PIC +; RUN: llc -march=mips64 < %s | FileCheck %s -check-prefix=MIPS64 +; RUN: llc -march=mips64 -relocation-model=pic < %s | FileCheck %s -check-prefix=MIPS64-PIC +; RUN: llc -march=mips -mattr=+micromips < %s | FileCheck %s -check-prefix=MIPS32-MM +; RUN: llc -march=mips -relocation-model=pic -mattr=+micromips < %s | FileCheck %s -check-prefix=MIPS32-MM-PIC + +; Test that checks ABI for _mcount calls. + +; Function Attrs: noinline nounwind optnone +define void @foo() #0 { +; MIPS32-LABEL: foo: +; MIPS32: # %bb.0: # %entry +; MIPS32-NEXT: addiu $sp, $sp, -24 +; MIPS32-NEXT: .cfi_def_cfa_offset 24 +; MIPS32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MIPS32-NEXT: .cfi_offset 31, -4 +; MIPS32-NEXT: move $1, $ra +; MIPS32-NEXT: jal _mcount +; MIPS32-NEXT: addiu $sp, $sp, -8 +; MIPS32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MIPS32-NEXT: jr $ra +; MIPS32-NEXT: addiu $sp, $sp, 24 +; +; MIPS32-PIC-LABEL: foo: +; MIPS32-PIC: # %bb.0: # %entry +; MIPS32-PIC-NEXT: lui $2, %hi(_gp_disp) +; MIPS32-PIC-NEXT: addiu $2, $2, %lo(_gp_disp) +; MIPS32-PIC-NEXT: addiu $sp, $sp, -24 +; MIPS32-PIC-NEXT: .cfi_def_cfa_offset 24 +; MIPS32-PIC-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MIPS32-PIC-NEXT: .cfi_offset 31, -4 +; MIPS32-PIC-NEXT: addu $gp, $2, $25 +; MIPS32-PIC-NEXT: lw $25, %call16(_mcount)($gp) +; MIPS32-PIC-NEXT: move $1, $ra +; MIPS32-PIC-NEXT: .reloc ($tmp0), R_MIPS_JALR, _mcount +; MIPS32-PIC-NEXT: $tmp0: +; MIPS32-PIC-NEXT: jalr $25 +; MIPS32-PIC-NEXT: addiu $sp, $sp, -8 +; MIPS32-PIC-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MIPS32-PIC-NEXT: jr $ra +; MIPS32-PIC-NEXT: addiu $sp, $sp, 24 +; +; MIPS64-LABEL: foo: +; MIPS64: # %bb.0: # %entry +; MIPS64-NEXT: daddiu $sp, $sp, -16 +; MIPS64-NEXT: .cfi_def_cfa_offset 16 +; MIPS64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; MIPS64-NEXT: .cfi_offset 31, -8 +; MIPS64-NEXT: or $1, $ra, $zero +; MIPS64-NEXT: jal _mcount +; MIPS64-NEXT: nop +; MIPS64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; MIPS64-NEXT: jr $ra +; MIPS64-NEXT: daddiu $sp, $sp, 16 +; +; MIPS64-PIC-LABEL: foo: +; MIPS64-PIC: # %bb.0: # %entry +; MIPS64-PIC-NEXT: daddiu $sp, $sp, -16 +; MIPS64-PIC-NEXT: .cfi_def_cfa_offset 16 +; MIPS64-PIC-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; MIPS64-PIC-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; MIPS64-PIC-NEXT: .cfi_offset 31, -8 +; MIPS64-PIC-NEXT: .cfi_offset 28, -16 +; MIPS64-PIC-NEXT: lui $1, %hi(%neg(%gp_rel(foo))) +; MIPS64-PIC-NEXT: daddu $1, $1, $25 +; MIPS64-PIC-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(foo))) +; MIPS64-PIC-NEXT: ld $25, %call16(_mcount)($gp) +; MIPS64-PIC-NEXT: or $1, $ra, $zero +; MIPS64-PIC-NEXT: .reloc .Ltmp0, R_MIPS_JALR, _mcount +; MIPS64-PIC-NEXT: .Ltmp0: +; MIPS64-PIC-NEXT: jalr $25 +; MIPS64-PIC-NEXT: nop +; MIPS64-PIC-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; MIPS64-PIC-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; MIPS64-PIC-NEXT: jr $ra +; MIPS64-PIC-NEXT: daddiu $sp, $sp, 16 +; +; MIPS32-MM-LABEL: foo: +; MIPS32-MM: # %bb.0: # %entry +; MIPS32-MM-NEXT: addiu $sp, $sp, -24 +; MIPS32-MM-NEXT: .cfi_def_cfa_offset 24 +; MIPS32-MM-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MIPS32-MM-NEXT: .cfi_offset 31, -4 +; MIPS32-MM-NEXT: move $1, $ra +; MIPS32-MM-NEXT: jal _mcount +; MIPS32-MM-NEXT: addiu $sp, $sp, -8 +; MIPS32-MM-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MIPS32-MM-NEXT: jr $ra +; MIPS32-MM-NEXT: addiu $sp, $sp, 24 +; +; MIPS32-MM-PIC-LABEL: foo: +; MIPS32-MM-PIC: # %bb.0: # %entry +; MIPS32-MM-PIC-NEXT: lui $2, %hi(_gp_disp) +; MIPS32-MM-PIC-NEXT: addiu $2, $2, %lo(_gp_disp) +; MIPS32-MM-PIC-NEXT: addiu $sp, $sp, -24 +; MIPS32-MM-PIC-NEXT: .cfi_def_cfa_offset 24 +; MIPS32-MM-PIC-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MIPS32-MM-PIC-NEXT: .cfi_offset 31, -4 +; MIPS32-MM-PIC-NEXT: addu $2, $2, $25 +; MIPS32-MM-PIC-NEXT: lw $25, %call16(_mcount)($2) +; MIPS32-MM-PIC-NEXT: move $gp, $2 +; MIPS32-MM-PIC-NEXT: move $1, $ra +; MIPS32-MM-PIC-NEXT: .reloc ($tmp0), R_MICROMIPS_JALR, _mcount +; MIPS32-MM-PIC-NEXT: $tmp0: +; MIPS32-MM-PIC-NEXT: jalr $25 +; MIPS32-MM-PIC-NEXT: addiu $sp, $sp, -8 +; MIPS32-MM-PIC-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MIPS32-MM-PIC-NEXT: jr $ra +; MIPS32-MM-PIC-NEXT: addiu $sp, $sp, 24 +entry: + ret void +} + +attributes #0 = { "instrument-function-entry-inlined"="_mcount" } -- 2.49.0