Index: lib/Target/Mips/MipsFastISel.cpp =================================================================== --- lib/Target/Mips/MipsFastISel.cpp +++ lib/Target/Mips/MipsFastISel.cpp @@ -10,10 +10,12 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLibraryInfo.h" #include "MipsCCState.h" +#include "MipsInstrInfo.h" #include "MipsRegisterInfo.h" #include "MipsISelLowering.h" #include "MipsMachineFunction.h" #include "MipsRegisterInfo.h" +#include "MipsSEInstrInfo.h" #include "MipsSubtarget.h" #include "MipsTargetMachine.h" @@ -45,6 +47,7 @@ void setKind(BaseKind K) { Kind = K; } BaseKind getKind() const { return Kind; } bool isRegBase() const { return Kind == RegBase; } + bool isFIBase() const { return Kind == FrameIndexBase; } void setReg(unsigned Reg) { assert(isRegBase() && "Invalid base register access!"); Base.Reg = Reg; @@ -53,6 +56,14 @@ assert(isRegBase() && "Invalid base register access!"); return Base.Reg; } + void setFI(unsigned FI) { + assert(isFIBase() && "Invalid base frame index access!"); + Base.FI = FI; + } + unsigned getFI() const { + assert(isFIBase() && "Invalid base frame index access!"); + return Base.FI; + } void setOffset(int64_t Offset_) { Offset = Offset_; } int64_t getOffset() const { return Offset; } void setGlobalValue(const GlobalValue *G) { GV = G; } @@ -308,14 +319,37 @@ } bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) { - // This construct looks a big awkward but it is how other ports handle this - // and as this function is more fully completed, these cases which - // return false will have additional code in them. // - if (isa(Obj)) + // This code is mostly cloned from AARch64 (which cloned it from earlier + // ports) + unsigned Opcode = Instruction::UserOp1; + if (const Instruction *I = dyn_cast(Obj)) { + // Don't walk into other basic blocks unless the object is an alloca from + // another block, otherwise it may not have a virtual register assigned. + if (FuncInfo.StaticAllocaMap.count(static_cast(Obj)) || + FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) { + Opcode = I->getOpcode(); + } + } else if (isa(Obj)) return false; - else if (isa(Obj)) + if (isa(Obj)) { + switch (Opcode) { + default: + break; + case Instruction::Alloca: { + const AllocaInst *AI = cast(Obj); + DenseMap::iterator SI = + FuncInfo.StaticAllocaMap.find(AI); + if (SI != FuncInfo.StaticAllocaMap.end()) { + Addr.setKind(Address::FrameIndexBase); + Addr.setFI(SI->second); + return true; + } + break; + } + } return false; + } Addr.setReg(getRegForValue(Obj)); return Addr.getReg() != 0; } @@ -521,8 +555,25 @@ default: return false; } - emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset()); - return true; + if (Addr.isRegBase()) { + emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset()); + return true; + } + if (Addr.isFIBase()) { + unsigned FI = Addr.getFI(); + unsigned Align = 4; + unsigned Offset = 0; + MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(FI), MachineMemOperand::MOLoad, + MFI.getObjectSize(FI), Align); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) + .addFrameIndex(FI) + .addImm(Offset) + .addMemOperand(MMO); + return true; + } + return false; } bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr, @@ -554,8 +605,27 @@ default: return false; } - emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset()); - return true; + if (Addr.isRegBase()) { + emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset()); + return true; + } + if (Addr.isFIBase()) { + unsigned FI = Addr.getFI(); + unsigned Align = 4; + unsigned Offset = 0; + MachineFrameInfo &MFI = *MF->getFrameInfo(); + ; + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(FI), MachineMemOperand::MOLoad, + MFI.getObjectSize(FI), Align); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)) + .addReg(SrcReg) + .addFrameIndex(FI) + .addImm(Offset) + .addMemOperand(MMO); + return true; + } + return false; } bool MipsFastISel::selectLoad(const Instruction *I) { @@ -974,15 +1044,6 @@ CLI.Call = MIB; - // Add implicit physical register uses to the call. - for (auto Reg : CLI.OutRegs) - MIB.addReg(Reg, RegState::Implicit); - - // Add a register mask with the call-preserved registers. Proper - // defs for return values will be added by setPhysRegsDeadExcept(). - MIB.addRegMask(TRI.getCallPreservedMask(CC)); - - CLI.Call = MIB; // Finish off the call including any return values. return finishCall(CLI, RetVT, NumBytes); } Index: test/CodeGen/Mips/Fast-ISel/load1.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/Fast-ISel/load1.ll @@ -0,0 +1,23 @@ +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32 \ +; RUN: < %s | FileCheck %s + +@z = common global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +; Function Attrs: nounwind +define void @foo(i32 signext %x) { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + %0 = load i32* %x.addr, align 4 + store i32 %0, i32* @z, align 4 +; CHECK: lw $[[REG_Z_ADDR:[0-9]+]], %got(z)(${{[0-9]+}}) +; CHECK: sw $4, [[LOCAL_X:[0-9]+]]($sp) +; CHECK: lw $[[TEMP:[0-9]+]], [[LOCAL_X]]($sp) +; CHECK: sw $[[TEMP]], 0($[[REG_Z_ADDR]]) + ret void +} + +