summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-02-14 20:56:18 +0000
committerTim Northover <tnorthover@apple.com>2017-02-14 20:56:18 +0000
commitc2f8956313bb4d32f4af13b097033b20cec0b3f4 (patch)
tree98794f9718339b25872e16a8502373f3a7b3b9d4 /llvm/lib/CodeGen
parentee29e42b3341e6d14bb55f9ad532941343a89a2f (diff)
downloadbcm5719-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.cpp31
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp11
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()) &&
OpenPOWER on IntegriCloud