summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMirko Brkusanin <Mirko.Brkusanin@rt-rk.com>2019-10-08 14:32:03 +0000
committerMirko Brkusanin <Mirko.Brkusanin@rt-rk.com>2019-10-08 14:32:03 +0000
commit45e0f2437327e753b0cd20fbe6fa25c8e1b226c7 (patch)
tree49e56d81f3c915f761557fcea0fc61a08c0a53ce /llvm/lib/Target
parent2cd0f2895946de546d066f67c88ff365d3210017 (diff)
downloadbcm5719-llvm-45e0f2437327e753b0cd20fbe6fa25c8e1b226c7.tar.gz
bcm5719-llvm-45e0f2437327e753b0cd20fbe6fa25c8e1b226c7.zip
[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 llvm-svn: 374055
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp45
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h4
2 files changed, 49 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index d9354cadc73..65afb3650f8 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/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<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);
}
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
index 80ab1ea9f63..39f665be571 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
+++ b/llvm/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,
OpenPOWER on IntegriCloud