From 6652a52e2b208ad593ff562667142affaec4a7df Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 28 Apr 2017 18:37:16 +0000 Subject: [PATCH] Use Argument::hasAttribute and AttributeList::ReturnIndex more This eliminates many extra 'Idx' induction variables in loops over arguments in CodeGen/ and Target/. It also reduces the number of places where we assume that ReturnIndex is 0 and that we should add one to argument numbers to get the corresponding attribute list index. NFC llvm-svn: 301666 --- llvm/include/llvm/IR/CallSite.h | 2 +- llvm/include/llvm/IR/Function.h | 8 +++-- llvm/lib/Analysis/CFLGraph.h | 2 +- .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 40 ++++++++++------------ llvm/lib/IR/AsmWriter.cpp | 32 ++++++++--------- llvm/lib/IR/Attributes.cpp | 29 ++++------------ llvm/lib/IR/Instructions.cpp | 3 +- llvm/lib/IR/Value.cpp | 4 +-- llvm/lib/Target/AArch64/AArch64FastISel.cpp | 15 ++++---- llvm/lib/Target/ARM/ARMFastISel.cpp | 24 ++++++------- llvm/lib/Target/Hexagon/HexagonBitTracker.cpp | 9 ++--- llvm/lib/Target/Mips/MipsFastISel.cpp | 27 +++++++-------- llvm/lib/Target/X86/X86FastISel.cpp | 15 ++++---- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 29 +++++++--------- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 5 +-- 15 files changed, 103 insertions(+), 141 deletions(-) diff --git a/llvm/include/llvm/IR/CallSite.h b/llvm/include/llvm/IR/CallSite.h index 79f5955..b1c8d3f 100644 --- a/llvm/include/llvm/IR/CallSite.h +++ b/llvm/include/llvm/IR/CallSite.h @@ -599,7 +599,7 @@ public: bool isReturnNonNull() const { if (hasRetAttr(Attribute::NonNull)) return true; - else if (getDereferenceableBytes(0) > 0 && + else if (getDereferenceableBytes(AttributeList::ReturnIndex) > 0 && getType()->getPointerAddressSpace() == 0) return true; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index a3762a44..f48d436 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -322,12 +322,14 @@ public: /// @brief Extract the number of dereferenceable bytes for a call or /// parameter (0=unknown). + /// @param i AttributeList index, referring to a return value or argument. uint64_t getDereferenceableBytes(unsigned i) const { return AttributeSets.getDereferenceableBytes(i); } /// @brief Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). + /// @param i AttributeList index, referring to a return value or argument. uint64_t getDereferenceableOrNullBytes(unsigned i) const { return AttributeSets.getDereferenceableOrNullBytes(i); } @@ -440,10 +442,10 @@ public: } /// @brief Determine if the function returns a structure through first - /// pointer argument. + /// or second pointer argument. bool hasStructRetAttr() const { - return AttributeSets.hasAttribute(1, Attribute::StructRet) || - AttributeSets.hasAttribute(2, Attribute::StructRet); + return AttributeSets.hasParamAttribute(0, Attribute::StructRet) || + AttributeSets.hasParamAttribute(1, Attribute::StructRet); } /// @brief Determine if the parameter or return value is marked with NoAlias diff --git a/llvm/lib/Analysis/CFLGraph.h b/llvm/lib/Analysis/CFLGraph.h index 75726e8..06410bf 100644 --- a/llvm/lib/Analysis/CFLGraph.h +++ b/llvm/lib/Analysis/CFLGraph.h @@ -429,7 +429,7 @@ template class CFLGraphBuilder { if (Inst->getType()->isPointerTy()) { auto *Fn = CS.getCalledFunction(); - if (Fn == nullptr || !Fn->doesNotAlias(0)) + if (Fn == nullptr || !Fn->doesNotAlias(AttributeList::ReturnIndex)) // No need to call addNode() since we've added Inst at the // beginning of this function and we know it is not a global. Graph.addAttr(InstantiatedValue{Inst, 0}, getAttrUnknown()); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index a9156d6..00f8162 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -8173,15 +8173,14 @@ void SelectionDAGISel::LowerArguments(const Function &F) { findArgumentCopyElisionCandidates(DL, FuncInfo, ArgCopyElisionCandidates); // Set up the incoming argument description vector. - unsigned Idx = 0; for (const Argument &Arg : F.args()) { - ++Idx; + unsigned ArgNo = Arg.getArgNo(); SmallVector ValueVTs; ComputeValueVTs(*TLI, DAG.getDataLayout(), Arg.getType(), ValueVTs); bool isArgValueUsed = !Arg.use_empty(); unsigned PartBase = 0; Type *FinalType = Arg.getType(); - if (F.getAttributes().hasAttribute(Idx, Attribute::ByVal)) + if (Arg.hasAttribute(Attribute::ByVal)) FinalType = cast(FinalType)->getElementType(); bool NeedsRegBlock = TLI->functionArgumentNeedsConsecutiveRegisters( FinalType, F.getCallingConv(), F.isVarArg()); @@ -8192,11 +8191,11 @@ void SelectionDAGISel::LowerArguments(const Function &F) { ISD::ArgFlagsTy Flags; unsigned OriginalAlignment = DL.getABITypeAlignment(ArgTy); - if (F.getAttributes().hasAttribute(Idx, Attribute::ZExt)) + if (Arg.hasAttribute(Attribute::ZExt)) Flags.setZExt(); - if (F.getAttributes().hasAttribute(Idx, Attribute::SExt)) + if (Arg.hasAttribute(Attribute::SExt)) Flags.setSExt(); - if (F.getAttributes().hasAttribute(Idx, Attribute::InReg)) { + if (Arg.hasAttribute(Attribute::InReg)) { // If we are using vectorcall calling convention, a structure that is // passed InReg - is surely an HVA if (F.getCallingConv() == CallingConv::X86_VectorCall && @@ -8209,15 +8208,15 @@ void SelectionDAGISel::LowerArguments(const Function &F) { // Set InReg Flag Flags.setInReg(); } - if (F.getAttributes().hasAttribute(Idx, Attribute::StructRet)) + if (Arg.hasAttribute(Attribute::StructRet)) Flags.setSRet(); - if (F.getAttributes().hasAttribute(Idx, Attribute::SwiftSelf)) + if (Arg.hasAttribute(Attribute::SwiftSelf)) Flags.setSwiftSelf(); - if (F.getAttributes().hasAttribute(Idx, Attribute::SwiftError)) + if (Arg.hasAttribute(Attribute::SwiftError)) Flags.setSwiftError(); - if (F.getAttributes().hasAttribute(Idx, Attribute::ByVal)) + if (Arg.hasAttribute(Attribute::ByVal)) Flags.setByVal(); - if (F.getAttributes().hasAttribute(Idx, Attribute::InAlloca)) { + if (Arg.hasAttribute(Attribute::InAlloca)) { Flags.setInAlloca(); // Set the byval flag for CCAssignFn callbacks that don't know about // inalloca. This way we can know how many bytes we should've allocated @@ -8228,7 +8227,7 @@ void SelectionDAGISel::LowerArguments(const Function &F) { } if (F.getCallingConv() == CallingConv::X86_INTR) { // IA Interrupt passes frame (1st parameter) by value in the stack. - if (Idx == 1) + if (ArgNo == 0) Flags.setByVal(); } if (Flags.isByVal() || Flags.isInAlloca()) { @@ -8238,13 +8237,13 @@ void SelectionDAGISel::LowerArguments(const Function &F) { // For ByVal, alignment should be passed from FE. BE will guess if // this info is not there but there are cases it cannot get right. unsigned FrameAlign; - if (F.getParamAlignment(Idx)) - FrameAlign = F.getParamAlignment(Idx); + if (Arg.getParamAlignment()) + FrameAlign = Arg.getParamAlignment(); else FrameAlign = TLI->getByValTypeAlignment(ElementTy, DL); Flags.setByValAlign(FrameAlign); } - if (F.getAttributes().hasAttribute(Idx, Attribute::Nest)) + if (Arg.hasAttribute(Attribute::Nest)) Flags.setNest(); if (NeedsRegBlock) Flags.setInConsecutiveRegs(); @@ -8256,7 +8255,7 @@ void SelectionDAGISel::LowerArguments(const Function &F) { unsigned NumRegs = TLI->getNumRegisters(*CurDAG->getContext(), VT); for (unsigned i = 0; i != NumRegs; ++i) { ISD::InputArg MyFlags(Flags, RegisterVT, VT, isArgValueUsed, - Idx-1, PartBase+i*RegisterVT.getStoreSize()); + ArgNo, PartBase+i*RegisterVT.getStoreSize()); if (NumRegs > 1 && i == 0) MyFlags.Flags.setSplit(); // if it isn't first piece, alignment must be 1 @@ -8297,7 +8296,6 @@ void SelectionDAGISel::LowerArguments(const Function &F) { // Set up the argument values. unsigned i = 0; - Idx = 0; if (!FuncInfo->CanLowerReturn) { // Create a virtual register for the sret pointer, and put in a copy // from the sret argument into it. @@ -8319,14 +8317,12 @@ void SelectionDAGISel::LowerArguments(const Function &F) { DAG.setRoot(NewRoot); // i indexes lowered arguments. Bump it past the hidden sret argument. - // Idx indexes LLVM arguments. Don't touch it. ++i; } SmallVector Chains; DenseMap ArgCopyElisionFrameIndexMap; for (const Argument &Arg : F.args()) { - ++Idx; SmallVector ArgValues; SmallVector ValueVTs; ComputeValueVTs(*TLI, DAG.getDataLayout(), Arg.getType(), ValueVTs); @@ -8348,7 +8344,7 @@ void SelectionDAGISel::LowerArguments(const Function &F) { // debugging information. bool isSwiftErrorArg = TLI->supportSwiftError() && - F.getAttributes().hasAttribute(Idx, Attribute::SwiftError); + Arg.hasAttribute(Attribute::SwiftError); if (!ArgHasUses && !isSwiftErrorArg) { SDB->setUnusedArgValue(&Arg, InVals[i]); @@ -8368,9 +8364,9 @@ void SelectionDAGISel::LowerArguments(const Function &F) { // function. if (ArgHasUses || isSwiftErrorArg) { Optional AssertOp; - if (F.getAttributes().hasAttribute(Idx, Attribute::SExt)) + if (Arg.hasAttribute(Attribute::SExt)) AssertOp = ISD::AssertSext; - else if (F.getAttributes().hasAttribute(Idx, Attribute::ZExt)) + else if (Arg.hasAttribute(Attribute::ZExt)) AssertOp = ISD::AssertZext; ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i], NumParts, diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index e396716..62bef4d 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2085,8 +2085,7 @@ public: void printModule(const Module *M); void writeOperand(const Value *Op, bool PrintType); - void writeParamOperand(const Value *Operand, AttributeList Attrs, - unsigned Idx); + void writeParamOperand(const Value *Operand, AttributeSet Attrs); void writeOperandBundles(ImmutableCallSite CS); void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope); void writeAtomicCmpXchg(AtomicOrdering SuccessOrdering, @@ -2102,7 +2101,7 @@ public: void printIndirectSymbol(const GlobalIndirectSymbol *GIS); void printComdat(const Comdat *C); void printFunction(const Function *F); - void printArgument(const Argument *FA, AttributeList Attrs, unsigned Idx); + void printArgument(const Argument *FA, AttributeSet Attrs); void printBasicBlock(const BasicBlock *BB); void printInstructionLine(const Instruction &I); void printInstruction(const Instruction &I); @@ -2181,7 +2180,7 @@ void AssemblyWriter::writeAtomicCmpXchg(AtomicOrdering SuccessOrdering, } void AssemblyWriter::writeParamOperand(const Value *Operand, - AttributeList Attrs, unsigned Idx) { + AttributeSet Attrs) { if (!Operand) { Out << ""; return; @@ -2190,8 +2189,8 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, // Print the type TypePrinter.print(Operand->getType(), Out); // Print parameter attributes list - if (Attrs.hasAttributes(Idx)) - Out << ' ' << Attrs.getAsString(Idx); + if (Attrs.hasAttributes()) + Out << ' ' << Attrs.getAsString(); Out << ' '; // Print the operand WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule); @@ -2654,17 +2653,17 @@ void AssemblyWriter::printFunction(const Function *F) { // Output type... TypePrinter.print(FT->getParamType(I), Out); - if (Attrs.hasAttributes(I + 1)) - Out << ' ' << Attrs.getAsString(I + 1); + AttributeSet ArgAttrs = Attrs.getParamAttributes(I); + if (ArgAttrs.hasAttributes()) + Out << ' ' << ArgAttrs.getAsString(); } } else { // The arguments are meaningful here, print them in detail. - unsigned Idx = 1; for (const Argument &Arg : F->args()) { // Insert commas as we go... the first arg doesn't get a comma - if (Idx != 1) + if (Arg.getArgNo() != 0) Out << ", "; - printArgument(&Arg, Attrs, Idx++); + printArgument(&Arg, Attrs.getParamAttributes(Arg.getArgNo())); } } @@ -2726,14 +2725,13 @@ void AssemblyWriter::printFunction(const Function *F) { /// printArgument - This member is called for every argument that is passed into /// the function. Simply print it out /// -void AssemblyWriter::printArgument(const Argument *Arg, AttributeList Attrs, - unsigned Idx) { +void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) { // Output type... TypePrinter.print(Arg->getType(), Out); // Output parameter attributes list - if (Attrs.hasAttributes(Idx)) - Out << ' ' << Attrs.getAsString(Idx); + if (Attrs.hasAttributes()) + Out << ' ' << Attrs.getAsString(); // Output name, if available... if (Arg->hasName()) { @@ -3027,7 +3025,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) { if (op > 0) Out << ", "; - writeParamOperand(CI->getArgOperand(op), PAL, op + 1); + writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op)); } // Emit an ellipsis if this is a musttail call in a vararg function. This @@ -3070,7 +3068,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) { if (op) Out << ", "; - writeParamOperand(II->getArgOperand(op), PAL, op + 1); + writeParamOperand(II->getArgOperand(op), PAL.getParamAttributes(op)); } Out << ')'; diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index e304145..6c4d0f0 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1363,15 +1363,7 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { } AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) { - for (Attribute Attr : A.getAttributes(Index)) { - if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { - removeAttribute(Attr.getKindAsEnum()); - } else { - assert(Attr.isStringAttribute() && "Invalid attribute type!"); - removeAttribute(Attr.getKindAsString()); - } - } - + remove(A.getAttributes(Index)); return *this; } @@ -1513,25 +1505,16 @@ bool AttrBuilder::hasAttributes() const { return !Attrs.none() || !TargetDepAttrs.empty(); } -bool AttrBuilder::hasAttributes(AttributeList A, uint64_t Index) const { - unsigned Slot = ~0U; - for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) - if (A.getSlotIndex(I) == Index) { - Slot = I; - break; - } - - assert(Slot != ~0U && "Couldn't find the index!"); +bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const { + AttributeSet AS = AL.getAttributes(Index); - for (AttributeList::iterator I = A.begin(Slot), E = A.end(Slot); I != E; - ++I) { - Attribute Attr = *I; + for (Attribute Attr : AS) { if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { - if (Attrs[I->getKindAsEnum()]) + if (contains(Attr.getKindAsEnum())) return true; } else { assert(Attr.isStringAttribute() && "Invalid attribute kind!"); - return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end(); + return contains(Attr.getKindAsString()); } } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 76582e3..5950099 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -501,7 +501,8 @@ static Instruction *createMalloc(Instruction *InsertBefore, MCall->setTailCall(); if (Function *F = dyn_cast(MallocFunc)) { MCall->setCallingConv(F->getCallingConv()); - if (!F->doesNotAlias(0)) F->setDoesNotAlias(0); + if (!F->doesNotAlias(AttributeList::ReturnIndex)) + F->setDoesNotAlias(AttributeList::ReturnIndex); } assert(!MCall->getType()->isVoidTy() && "Malloc has void return type"); diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index cdf2a4a..d0e25f3 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -578,9 +578,9 @@ unsigned Value::getPointerDereferenceableBytes(const DataLayout &DL, CanBeNull = true; } } else if (auto CS = ImmutableCallSite(this)) { - DerefBytes = CS.getDereferenceableBytes(0); + DerefBytes = CS.getDereferenceableBytes(AttributeList::ReturnIndex); if (DerefBytes == 0) { - DerefBytes = CS.getDereferenceableOrNullBytes(0); + DerefBytes = CS.getDereferenceableOrNullBytes(AttributeList::ReturnIndex); CanBeNull = true; } } else if (const LoadInst *LI = dyn_cast(this)) { diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index 4e5e3e4..0837080 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -2907,16 +2907,13 @@ bool AArch64FastISel::fastLowerArguments() { // Only handle simple cases of up to 8 GPR and FPR each. unsigned GPRCnt = 0; unsigned FPRCnt = 0; - unsigned Idx = 0; for (auto const &Arg : F->args()) { - // The first argument is at index 1. - ++Idx; - 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)) + if (Arg.hasAttribute(Attribute::ByVal) || + Arg.hasAttribute(Attribute::InReg) || + Arg.hasAttribute(Attribute::StructRet) || + Arg.hasAttribute(Attribute::SwiftSelf) || + Arg.hasAttribute(Attribute::SwiftError) || + Arg.hasAttribute(Attribute::Nest)) return false; Type *ArgTy = Arg.getType(); diff --git a/llvm/lib/Target/ARM/ARMFastISel.cpp b/llvm/lib/Target/ARM/ARMFastISel.cpp index e9bc7db..56cac85 100644 --- a/llvm/lib/Target/ARM/ARMFastISel.cpp +++ b/llvm/lib/Target/ARM/ARMFastISel.cpp @@ -3025,20 +3025,18 @@ bool ARMFastISel::fastLowerArguments() { // Only handle simple cases. i.e. Up to 4 i8/i16/i32 scalar arguments // which are passed in r0 - r3. - unsigned Idx = 1; - for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); - I != E; ++I, ++Idx) { - if (Idx > 4) + for (const Argument &Arg : F->args()) { + if (Arg.getArgNo() >= 4) return false; - if (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::ByVal)) + if (Arg.hasAttribute(Attribute::InReg) || + Arg.hasAttribute(Attribute::StructRet) || + Arg.hasAttribute(Attribute::SwiftSelf) || + Arg.hasAttribute(Attribute::SwiftError) || + Arg.hasAttribute(Attribute::ByVal)) return false; - Type *ArgTy = I->getType(); + Type *ArgTy = Arg.getType(); if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) return false; @@ -3059,10 +3057,10 @@ bool ARMFastISel::fastLowerArguments() { }; const TargetRegisterClass *RC = &ARM::rGPRRegClass; - Idx = 0; for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); - I != E; ++I, ++Idx) { - unsigned SrcReg = GPRArgRegs[Idx]; + I != E; ++I) { + unsigned ArgNo = I->getArgNo(); + unsigned SrcReg = GPRArgRegs[ArgNo]; unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC); // FIXME: Unfortunately it's necessary to emit a copy from the livein copy. // Without this, EmitLiveInCopies may eliminate the livein if its only diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp index 90ccecb..af0f8b2 100644 --- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp +++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp @@ -57,12 +57,10 @@ HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri, // tion). To avoid the complications with in-memory arguments, only consi- // der the initial sequence of formal parameters that are known to be // passed via registers. - unsigned AttrIdx = 0; unsigned InVirtReg, InPhysReg = 0; const Function &F = *MF.getFunction(); typedef Function::const_arg_iterator arg_iterator; for (arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - AttrIdx++; const Argument &Arg = *I; Type *ATy = Arg.getType(); unsigned Width = 0; @@ -74,8 +72,7 @@ HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri, // Module::AnyPointerSize. if (Width == 0 || Width > 64) break; - AttributeList Attrs = F.getAttributes(); - if (Attrs.hasAttribute(AttrIdx, Attribute::ByVal)) + if (Arg.hasAttribute(Attribute::ByVal)) continue; InPhysReg = getNextPhysReg(InPhysReg, Width); if (!InPhysReg) @@ -83,9 +80,9 @@ HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri, InVirtReg = getVirtRegFor(InPhysReg); if (!InVirtReg) continue; - if (Attrs.hasAttribute(AttrIdx, Attribute::SExt)) + if (Arg.hasAttribute(Attribute::SExt)) VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width))); - else if (Attrs.hasAttribute(AttrIdx, Attribute::ZExt)) + else if (Arg.hasAttribute(Attribute::ZExt)) VRX.insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width))); } } diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index a5c7bf7..d1ec77e 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -1326,11 +1326,10 @@ bool MipsFastISel::fastLowerArguments() { // Only handle simple cases. i.e. All arguments are directly mapped to // registers of the appropriate type. SmallVector Allocation; - unsigned Idx = 1; for (const auto &FormalArg : F->args()) { - if (F->getAttributes().hasAttribute(Idx, Attribute::InReg) || - F->getAttributes().hasAttribute(Idx, Attribute::StructRet) || - F->getAttributes().hasAttribute(Idx, Attribute::ByVal)) { + if (FormalArg.hasAttribute(Attribute::InReg) || + FormalArg.hasAttribute(Attribute::StructRet) || + FormalArg.hasAttribute(Attribute::ByVal)) { DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n"); return false; } @@ -1342,7 +1341,8 @@ bool MipsFastISel::fastLowerArguments() { } EVT ArgVT = TLI.getValueType(DL, ArgTy); - DEBUG(dbgs() << ".. " << (Idx - 1) << ": " << ArgVT.getEVTString() << "\n"); + DEBUG(dbgs() << ".. " << FormalArg.getArgNo() << ": " + << ArgVT.getEVTString() << "\n"); if (!ArgVT.isSimple()) { DEBUG(dbgs() << ".. .. gave up (not a simple type)\n"); return false; @@ -1352,8 +1352,8 @@ bool MipsFastISel::fastLowerArguments() { case MVT::i1: case MVT::i8: case MVT::i16: - if (!F->getAttributes().hasAttribute(Idx, Attribute::SExt) && - !F->getAttributes().hasAttribute(Idx, Attribute::ZExt)) { + if (!FormalArg.hasAttribute(Attribute::SExt) && + !FormalArg.hasAttribute(Attribute::ZExt)) { // It must be any extend, this shouldn't happen for clang-generated IR // so just fall back on SelectionDAG. DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n"); @@ -1374,7 +1374,7 @@ bool MipsFastISel::fastLowerArguments() { break; case MVT::i32: - if (F->getAttributes().hasAttribute(Idx, Attribute::ZExt)) { + if (FormalArg.hasAttribute(Attribute::ZExt)) { // The O32 ABI does not permit a zero-extended i32. DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n"); return false; @@ -1437,23 +1437,20 @@ bool MipsFastISel::fastLowerArguments() { DEBUG(dbgs() << ".. .. gave up (unknown type)\n"); return false; } - - ++Idx; } - Idx = 0; for (const auto &FormalArg : F->args()) { - unsigned SrcReg = Allocation[Idx].Reg; - unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[Idx].RC); + unsigned ArgNo = FormalArg.getArgNo(); + unsigned SrcReg = Allocation[ArgNo].Reg; + unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC); // FIXME: Unfortunately it's necessary to emit a copy from the livein copy. // Without this, EmitLiveInCopies may eliminate the livein if its only // use is a bitcast (which isn't turned into an instruction). - unsigned ResultReg = createResultReg(Allocation[Idx].RC); + unsigned ResultReg = createResultReg(Allocation[ArgNo].RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::COPY), ResultReg) .addReg(DstReg, getKillRegState(true)); updateValueMap(&FormalArg, ResultReg); - ++Idx; } // Calculate the size of the incoming arguments area. diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index b847781..fd11b67 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -3074,16 +3074,13 @@ bool X86FastISel::fastLowerArguments() { // Only handle simple cases. i.e. Up to 6 i32/i64 scalar arguments. unsigned GPRCnt = 0; unsigned FPRCnt = 0; - unsigned Idx = 0; for (auto const &Arg : F->args()) { - // The first argument is at index 1. - ++Idx; - 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)) + if (Arg.hasAttribute(Attribute::ByVal) || + Arg.hasAttribute(Attribute::InReg) || + Arg.hasAttribute(Attribute::StructRet) || + Arg.hasAttribute(Attribute::SwiftSelf) || + Arg.hasAttribute(Attribute::SwiftError) || + Arg.hasAttribute(Attribute::Nest)) return false; Type *ArgTy = Arg.getType(); diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index a2c8a32..25db0ef 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -106,9 +106,9 @@ doPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, AttributeList PAL = F->getAttributes(); // First, determine the new argument list - unsigned ArgIndex = 0; + unsigned ArgNo = 0; for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; - ++I, ++ArgIndex) { + ++I, ++ArgNo) { if (ByValArgsToTransform.count(&*I)) { // Simple byval argument? Just add all the struct element types. Type *AgTy = cast(I->getType())->getElementType(); @@ -120,7 +120,7 @@ doPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, } else if (!ArgsToPromote.count(&*I)) { // Unchanged argument Params.push_back(I->getType()); - ArgAttrVec.push_back(PAL.getParamAttributes(ArgIndex)); + ArgAttrVec.push_back(PAL.getParamAttributes(ArgNo)); } else if (I->use_empty()) { // Dead argument (which are always marked as promotable) ++NumArgumentsDead; @@ -214,12 +214,12 @@ doPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, // Loop over the operands, inserting GEP and loads in the caller as // appropriate. CallSite::arg_iterator AI = CS.arg_begin(); - ArgIndex = 1; + ArgNo = 0; for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; - ++I, ++AI, ++ArgIndex) + ++I, ++AI, ++ArgNo) if (!ArgsToPromote.count(&*I) && !ByValArgsToTransform.count(&*I)) { Args.push_back(*AI); // Unmodified argument - ArgAttrVec.push_back(CallPAL.getAttributes(ArgIndex)); + ArgAttrVec.push_back(CallPAL.getParamAttributes(ArgNo)); } else if (ByValArgsToTransform.count(&*I)) { // Emit a GEP and load for each element of the struct. Type *AgTy = cast(I->getType())->getElementType(); @@ -280,9 +280,9 @@ doPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, } // Push any varargs arguments on the list. - for (; AI != CS.arg_end(); ++AI, ++ArgIndex) { + for (; AI != CS.arg_end(); ++AI, ++ArgNo) { Args.push_back(*AI); - ArgAttrVec.push_back(CallPAL.getAttributes(ArgIndex)); + ArgAttrVec.push_back(CallPAL.getParamAttributes(ArgNo)); } SmallVector OpBundles; @@ -839,17 +839,12 @@ promoteArguments(Function *F, function_ref AARGetter, // avoiding a register copy. if (PtrArg->hasStructRetAttr()) { unsigned ArgNo = PtrArg->getArgNo(); - F->setAttributes( - F->getAttributes() - .removeAttribute(F->getContext(), ArgNo + 1, Attribute::StructRet) - .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias)); + F->removeAttribute(ArgNo + 1, Attribute::StructRet); + F->addAttribute(ArgNo + 1, Attribute::NoAlias); for (Use &U : F->uses()) { CallSite CS(U.getUser()); - CS.setAttributes( - CS.getAttributes() - .removeAttribute(F->getContext(), ArgNo + 1, - Attribute::StructRet) - .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias)); + CS.removeAttribute(ArgNo + 1, Attribute::StructRet); + CS.addAttribute(ArgNo + 1, Attribute::NoAlias); } } diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 9648883..031c3d8a 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -855,10 +855,11 @@ static bool addNoAliasAttrs(const SCCNodeSet &SCCNodes) { bool MadeChange = false; for (Function *F : SCCNodes) { - if (F->doesNotAlias(0) || !F->getReturnType()->isPointerTy()) + if (F->doesNotAlias(AttributeList::ReturnIndex) || + !F->getReturnType()->isPointerTy()) continue; - F->setDoesNotAlias(0); + F->setDoesNotAlias(AttributeList::ReturnIndex); ++NumNoAlias; MadeChange = true; } -- 2.7.4