]> granicus.if.org Git - llvm/commitdiff
[Mips] Emit proper ABI for _mcount calls
authorMirko Brkusanin <Mirko.Brkusanin@rt-rk.com>
Tue, 8 Oct 2019 14:32:03 +0000 (14:32 +0000)
committerMirko Brkusanin <Mirko.Brkusanin@rt-rk.com>
Tue, 8 Oct 2019 14:32:03 +0000 (14:32 +0000)
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
lib/Target/Mips/MipsSEISelDAGToDAG.h
test/CodeGen/Mips/mcount.ll [new file with mode: 0644]

index d9354cadc73b7ff5584bc3dfc1d313dc42bb5e2f..65afb3650f8000f7575b61d8740ba78532dd26d6 100644 (file)
@@ -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<MipsFunctionInfo>()->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);
       }
index 80ab1ea9f635f3e58ded87dc49eded071df1a8ea..39f665be571e38da6e86009c37e3bdef8eead2cd 100644 (file)
@@ -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 (file)
index 0000000..e136ae0
--- /dev/null
@@ -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" }