mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-16 11:30:51 +00:00
Prevent instructions using $gp from being placed between a jalr and the instruction that restores the clobbered $gp.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130847 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
597a7664e1
commit
6b7588e6c4
@ -26,6 +26,7 @@ namespace llvm {
|
||||
FunctionPass *createMipsISelDag(MipsTargetMachine &TM);
|
||||
FunctionPass *createMipsDelaySlotFillerPass(MipsTargetMachine &TM);
|
||||
FunctionPass *createMipsExpandPseudoPass(MipsTargetMachine &TM);
|
||||
FunctionPass *createMipsEmitGPRestorePass(MipsTargetMachine &TM);
|
||||
|
||||
extern Target TheMipsTarget;
|
||||
extern Target TheMipselTarget;
|
||||
|
80
lib/Target/Mips/MipsEmitGPRestore.cpp
Normal file
80
lib/Target/Mips/MipsEmitGPRestore.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
//===-- MipsEmitGPRestore.cpp - Emit GP restore instruction-----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===-----------------------------------------------------------------------===//
|
||||
//
|
||||
// This pass emits instructions that restore $gp right
|
||||
// after jalr instructions.
|
||||
//
|
||||
//===-----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "emit-gp-restore"
|
||||
|
||||
#include "Mips.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "MipsMachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
struct Inserter : public MachineFunctionPass {
|
||||
|
||||
TargetMachine &TM;
|
||||
const TargetInstrInfo *TII;
|
||||
|
||||
static char ID;
|
||||
Inserter(TargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Mips Emit GP Restore";
|
||||
}
|
||||
|
||||
bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
};
|
||||
char Inserter::ID = 0;
|
||||
} // end of anonymous namespace
|
||||
|
||||
bool Inserter::runOnMachineFunction(MachineFunction &F) {
|
||||
if (TM.getRelocationModel() != Reloc::PIC_)
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
int FI = F.getInfo<MipsFunctionInfo>()->getGPFI();
|
||||
|
||||
for (MachineFunction::iterator MFI = F.begin(), MFE = F.end();
|
||||
MFI != MFE; ++MFI) {
|
||||
MachineBasicBlock& MBB = *MFI;
|
||||
MachineBasicBlock::iterator I = MFI->begin();
|
||||
|
||||
while (I != MFI->end()) {
|
||||
if (I->getOpcode() != Mips::JALR) {
|
||||
++I;
|
||||
continue;
|
||||
}
|
||||
|
||||
DebugLoc dl = I->getDebugLoc();
|
||||
// emit lw $gp, ($gp save slot on stack) after jalr
|
||||
BuildMI(MBB, ++I, dl, TII->get(Mips::LW), Mips::GP).addImm(0).addFrameIndex(FI);
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
/// createMipsEmitGPRestorePass - Returns a pass that emits instructions that
|
||||
/// restores $gp clobbered by jalr instructions.
|
||||
FunctionPass *llvm::createMipsEmitGPRestorePass(MipsTargetMachine &tm) {
|
||||
return new Inserter(tm);
|
||||
}
|
||||
|
@ -1298,17 +1298,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
||||
}
|
||||
MipsFI->setGPStackOffset(LastArgStackLoc);
|
||||
}
|
||||
|
||||
// Reload GP value.
|
||||
FI = MipsFI->getGPFI();
|
||||
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
|
||||
SDValue GPLoad = DAG.getLoad(MVT::i32, dl, Chain, FIN,
|
||||
MachinePointerInfo::getFixedStack(FI),
|
||||
false, false, 0);
|
||||
Chain = GPLoad.getValue(1);
|
||||
Chain = DAG.getCopyToReg(Chain, dl, DAG.getRegister(Mips::GP, MVT::i32),
|
||||
GPLoad, SDValue(0,0));
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
// Create the CALLSEQ_END node.
|
||||
|
@ -76,6 +76,12 @@ addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsTargetMachine::
|
||||
addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createMipsEmitGPRestorePass(*this));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsTargetMachine::
|
||||
addPostRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createMipsExpandPseudoPass(*this));
|
||||
|
@ -63,6 +63,8 @@ namespace llvm {
|
||||
CodeGenOpt::Level OptLevel);
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
virtual bool addPreRegAlloc(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
virtual bool addPostRegAlloc(PassManagerBase &, CodeGenOpt::Level);
|
||||
};
|
||||
|
||||
|
35
test/CodeGen/Mips/gprestore.ll
Normal file
35
test/CodeGen/Mips/gprestore.ll
Normal file
@ -0,0 +1,35 @@
|
||||
; RUN: llc -march=mips < %s | FileCheck %s
|
||||
|
||||
@p = external global i32
|
||||
@q = external global i32
|
||||
@r = external global i32
|
||||
|
||||
define void @f0() nounwind {
|
||||
entry:
|
||||
; CHECK: jalr
|
||||
; CHECK-NOT: got({{.*}})($gp)
|
||||
; CHECK: lw $gp
|
||||
; CHECK: jalr
|
||||
; CHECK-NOT: got({{.*}})($gp)
|
||||
; CHECK: lw $gp
|
||||
; CHECK: jalr
|
||||
; CHECK-NOT: got({{.*}})($gp)
|
||||
; CHECK: lw $gp
|
||||
tail call void (...)* @f1() nounwind
|
||||
%tmp = load i32* @p, align 4, !tbaa !0
|
||||
tail call void @f2(i32 %tmp) nounwind
|
||||
%tmp1 = load i32* @q, align 4, !tbaa !0
|
||||
%tmp2 = load i32* @r, align 4, !tbaa !0
|
||||
tail call void @f3(i32 %tmp1, i32 %tmp2) nounwind
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @f1(...)
|
||||
|
||||
declare void @f2(i32)
|
||||
|
||||
declare void @f3(i32, i32)
|
||||
|
||||
!0 = metadata !{metadata !"int", metadata !1}
|
||||
!1 = metadata !{metadata !"omnipotent char", metadata !2}
|
||||
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s -march=mips | FileCheck %s
|
||||
; RUN: llc < %s -march=mipsel -mcpu=4ke | FileCheck %s
|
||||
|
||||
@caller.sf1 = internal unnamed_addr global void (...)* null, align 4
|
||||
@gf1 = external global void (...)*
|
||||
|
Loading…
Reference in New Issue
Block a user