diff options
author | Tim Northover <tnorthover@apple.com> | 2017-02-14 20:56:18 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2017-02-14 20:56:18 +0000 |
commit | c2f8956313bb4d32f4af13b097033b20cec0b3f4 (patch) | |
tree | 98794f9718339b25872e16a8502373f3a7b3b9d4 /llvm/lib/CodeGen | |
parent | ee29e42b3341e6d14bb55f9ad532941343a89a2f (diff) | |
download | bcm5719-llvm-c2f8956313bb4d32f4af13b097033b20cec0b3f4.tar.gz bcm5719-llvm-c2f8956313bb4d32f4af13b097033b20cec0b3f4.zip |
GlobalISel: introduce G_PTR_MASK to simplify alloca handling.
This instruction clears the low bits of a pointer without requiring (possibly
dodgy if pointers aren't ints) conversions to and from an integer. Since (as
far as I'm aware) all masks are statically known, the instruction takes an
immediate operand rather than a register to specify the mask.
llvm-svn: 295103
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 11 |
2 files changed, 19 insertions, 23 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 143134758c3..c5ac42f4430 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -870,7 +870,7 @@ bool IRTranslator::translateAlloca(const User &U, unsigned AllocSize = MRI->createGenericVirtualRegister(IntPtrTy); unsigned TySize = MRI->createGenericVirtualRegister(IntPtrTy); - MIRBuilder.buildConstant(TySize, DL->getTypeAllocSize(Ty)); + MIRBuilder.buildConstant(TySize, -DL->getTypeAllocSize(Ty)); MIRBuilder.buildMul(AllocSize, NumElts, TySize); LLT PtrTy = LLT{*AI.getType(), *DL}; @@ -880,11 +880,8 @@ bool IRTranslator::translateAlloca(const User &U, unsigned SPTmp = MRI->createGenericVirtualRegister(PtrTy); MIRBuilder.buildCopy(SPTmp, SPReg); - unsigned SPInt = MRI->createGenericVirtualRegister(IntPtrTy); - MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT).addDef(SPInt).addUse(SPTmp); - - unsigned AllocInt = MRI->createGenericVirtualRegister(IntPtrTy); - MIRBuilder.buildSub(AllocInt, SPInt, AllocSize); + unsigned AllocTmp = MRI->createGenericVirtualRegister(PtrTy); + MIRBuilder.buildGEP(AllocTmp, SPTmp, AllocSize); // Handle alignment. We have to realign if the allocation granule was smaller // than stack alignment, or the specific alloca requires more than stack @@ -896,25 +893,13 @@ bool IRTranslator::translateAlloca(const User &U, // Round the size of the allocation up to the stack alignment size // by add SA-1 to the size. This doesn't overflow because we're computing // an address inside an alloca. - unsigned TmpSize = MRI->createGenericVirtualRegister(IntPtrTy); - unsigned AlignMinus1 = MRI->createGenericVirtualRegister(IntPtrTy); - MIRBuilder.buildConstant(AlignMinus1, Align - 1); - MIRBuilder.buildSub(TmpSize, AllocInt, AlignMinus1); - - unsigned AlignedAlloc = MRI->createGenericVirtualRegister(IntPtrTy); - unsigned AlignMask = MRI->createGenericVirtualRegister(IntPtrTy); - MIRBuilder.buildConstant(AlignMask, -(uint64_t)Align); - MIRBuilder.buildAnd(AlignedAlloc, TmpSize, AlignMask); - - AllocInt = AlignedAlloc; + unsigned AlignedAlloc = MRI->createGenericVirtualRegister(PtrTy); + MIRBuilder.buildPtrMask(AlignedAlloc, AllocTmp, Log2_32(Align)); + AllocTmp = AlignedAlloc; } - unsigned DstReg = getOrCreateVReg(AI); - MIRBuilder.buildInstr(TargetOpcode::G_INTTOPTR) - .addDef(DstReg) - .addUse(AllocInt); - - MIRBuilder.buildCopy(SPReg, DstReg); + MIRBuilder.buildCopy(SPReg, AllocTmp); + MIRBuilder.buildCopy(getOrCreateVReg(AI), AllocTmp); MF->getFrameInfo().CreateVariableSizedObject(Align ? Align : 1, &AI); assert(MF->getFrameInfo().hasVarSizedObjects()); diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 665fb7057df..d92bbc1c246 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -187,6 +187,17 @@ MachineInstrBuilder MachineIRBuilder::buildGEP(unsigned Res, unsigned Op0, .addUse(Op1); } +MachineInstrBuilder MachineIRBuilder::buildPtrMask(unsigned Res, unsigned Op0, + uint32_t NumBits) { + assert(MRI->getType(Res).isPointer() && + MRI->getType(Res) == MRI->getType(Op0) && "type mismatch"); + + return buildInstr(TargetOpcode::G_PTR_MASK) + .addDef(Res) + .addUse(Op0) + .addImm(NumBits); +} + MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0, unsigned Op1) { assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) && |