diff options
Diffstat (limited to 'lib/Target/AArch64/AArch64FastISel.cpp')
| -rw-r--r-- | lib/Target/AArch64/AArch64FastISel.cpp | 81 |
1 files changed, 55 insertions, 26 deletions
diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index 0ac4b39b0357..e2ab7ab79be1 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -37,7 +37,6 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Operator.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Support/CommandLine.h" using namespace llvm; namespace { @@ -144,8 +143,8 @@ private: bool computeCallAddress(const Value *V, Address &Addr); bool simplifyAddress(Address &Addr, MVT VT); void addLoadStoreOperands(Address &Addr, const MachineInstrBuilder &MIB, - unsigned Flags, unsigned ScaleFactor, - MachineMemOperand *MMO); + MachineMemOperand::Flags Flags, + unsigned ScaleFactor, MachineMemOperand *MMO); bool isMemCpySmall(uint64_t Len, unsigned Alignment); bool tryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len, unsigned Alignment); @@ -439,9 +438,6 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) { .addReg(ADRPReg) .addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - } else if (OpFlags & AArch64II::MO_CONSTPOOL) { - // We can't handle addresses loaded from a constant pool quickly yet. - return 0; } else { // ADRP + ADDX BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP), @@ -555,10 +551,9 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty) // Iterate through the GEP folding the constants into offsets where // we can. - gep_type_iterator GTI = gep_type_begin(U); - for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e; - ++i, ++GTI) { - const Value *Op = *i; + for (gep_type_iterator GTI = gep_type_begin(U), E = gep_type_end(U); + GTI != E; ++GTI) { + const Value *Op = GTI.getOperand(); if (StructType *STy = dyn_cast<StructType>(*GTI)) { const StructLayout *SL = DL.getStructLayout(STy); unsigned Idx = cast<ConstantInt>(Op)->getZExtValue(); @@ -947,10 +942,7 @@ bool AArch64FastISel::isValueAvailable(const Value *V) const { return true; const auto *I = cast<Instruction>(V); - if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) - return true; - - return false; + return FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB; } bool AArch64FastISel::simplifyAddress(Address &Addr, MVT VT) { @@ -1048,7 +1040,7 @@ bool AArch64FastISel::simplifyAddress(Address &Addr, MVT VT) { void AArch64FastISel::addLoadStoreOperands(Address &Addr, const MachineInstrBuilder &MIB, - unsigned Flags, + MachineMemOperand::Flags Flags, unsigned ScaleFactor, MachineMemOperand *MMO) { int64_t Offset = Addr.getOffset() / ScaleFactor; @@ -1612,8 +1604,8 @@ unsigned AArch64FastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT, unsigned AArch64FastISel::emitLogicalOp_ri(unsigned ISDOpc, MVT RetVT, unsigned LHSReg, bool LHSIsKill, uint64_t Imm) { - assert((ISD::AND + 1 == ISD::OR) && (ISD::AND + 2 == ISD::XOR) && - "ISD nodes are not consecutive!"); + static_assert((ISD::AND + 1 == ISD::OR) && (ISD::AND + 2 == ISD::XOR), + "ISD nodes are not consecutive!"); static const unsigned OpcTable[3][2] = { { AArch64::ANDWri, AArch64::ANDXri }, { AArch64::ORRWri, AArch64::ORRXri }, @@ -1659,8 +1651,8 @@ unsigned AArch64FastISel::emitLogicalOp_rs(unsigned ISDOpc, MVT RetVT, unsigned LHSReg, bool LHSIsKill, unsigned RHSReg, bool RHSIsKill, uint64_t ShiftImm) { - assert((ISD::AND + 1 == ISD::OR) && (ISD::AND + 2 == ISD::XOR) && - "ISD nodes are not consecutive!"); + static_assert((ISD::AND + 1 == ISD::OR) && (ISD::AND + 2 == ISD::XOR), + "ISD nodes are not consecutive!"); static const unsigned OpcTable[3][2] = { { AArch64::ANDWrs, AArch64::ANDXrs }, { AArch64::ORRWrs, AArch64::ORRXrs }, @@ -1904,6 +1896,21 @@ bool AArch64FastISel::selectLoad(const Instruction *I) { cast<LoadInst>(I)->isAtomic()) return false; + const Value *SV = I->getOperand(0); + if (TLI.supportSwiftError()) { + // Swifterror values can come from either a function parameter with + // swifterror attribute or an alloca with swifterror attribute. + if (const Argument *Arg = dyn_cast<Argument>(SV)) { + if (Arg->hasSwiftErrorAttr()) + return false; + } + + if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(SV)) { + if (Alloca->isSwiftError()) + return false; + } + } + // See if we can handle this address. Address Addr; if (!computeAddress(I->getOperand(0), Addr, I->getType())) @@ -2068,6 +2075,21 @@ bool AArch64FastISel::selectStore(const Instruction *I) { cast<StoreInst>(I)->isAtomic()) return false; + const Value *PtrV = I->getOperand(1); + if (TLI.supportSwiftError()) { + // Swifterror values can come from either a function parameter with + // swifterror attribute or an alloca with swifterror attribute. + if (const Argument *Arg = dyn_cast<Argument>(PtrV)) { + if (Arg->hasSwiftErrorAttr()) + return false; + } + + if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrV)) { + if (Alloca->isSwiftError()) + return false; + } + } + // Get the value to be stored into a register. Use the zero register directly // when possible to avoid an unnecessary copy and a wasted register. unsigned SrcReg = 0; @@ -2813,6 +2835,8 @@ bool AArch64FastISel::fastLowerArguments() { if (F->getAttributes().hasAttribute(Idx, Attribute::ByVal) || F->getAttributes().hasAttribute(Idx, Attribute::InReg) || F->getAttributes().hasAttribute(Idx, Attribute::StructRet) || + F->getAttributes().hasAttribute(Idx, Attribute::SwiftSelf) || + F->getAttributes().hasAttribute(Idx, Attribute::SwiftError) || F->getAttributes().hasAttribute(Idx, Attribute::Nest)) return false; @@ -3064,7 +3088,8 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) { return false; for (auto Flag : CLI.OutFlags) - if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal()) + if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal() || + Flag.isSwiftSelf() || Flag.isSwiftError()) return false; // Set up the argument vectors. @@ -3646,6 +3671,10 @@ bool AArch64FastISel::selectRet(const Instruction *I) { if (F.isVarArg()) return false; + if (TLI.supportSwiftError() && + F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) + return false; + if (TLI.supportSplitCSR(FuncInfo.MF)) return false; @@ -4814,18 +4843,18 @@ bool AArch64FastISel::selectGetElementPtr(const Instruction *I) { // Keep a running tab of the total offset to coalesce multiple N = N + Offset // into a single N = N + TotalOffset. uint64_t TotalOffs = 0; - Type *Ty = I->getOperand(0)->getType(); MVT VT = TLI.getPointerTy(DL); - for (auto OI = std::next(I->op_begin()), E = I->op_end(); OI != E; ++OI) { - const Value *Idx = *OI; - if (auto *StTy = dyn_cast<StructType>(Ty)) { + for (gep_type_iterator GTI = gep_type_begin(I), E = gep_type_end(I); + GTI != E; ++GTI) { + const Value *Idx = GTI.getOperand(); + if (auto *StTy = dyn_cast<StructType>(*GTI)) { unsigned Field = cast<ConstantInt>(Idx)->getZExtValue(); // N = N + Offset if (Field) TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field); - Ty = StTy->getElementType(Field); } else { - Ty = cast<SequentialType>(Ty)->getElementType(); + Type *Ty = GTI.getIndexedType(); + // If this is a constant subscript, handle it quickly. if (const auto *CI = dyn_cast<ConstantInt>(Idx)) { if (CI->isZero()) |
