22 #define DEBUG_TYPE "scalarrepl"
55 STATISTIC(NumReplaced,
"Number of allocas broken up");
56 STATISTIC(NumPromoted,
"Number of allocas promoted");
57 STATISTIC(NumAdjusted,
"Number of scalar allocas adjusted to allow promotion");
58 STATISTIC(NumConverted,
"Number of aggregates converted to scalar");
62 SROA(
int T,
bool hasDT,
char &
ID,
int ST,
int AT,
int SLT)
69 StructMemberThreshold = 32;
71 StructMemberThreshold =
ST;
73 ArrayElementThreshold = 8;
75 ArrayElementThreshold = AT;
78 ScalarLoadThreshold = -1;
80 ScalarLoadThreshold = SLT;
111 bool isMemCpySrc : 1;
114 bool isMemCpyDst : 1;
119 bool hasSubelementAccess : 1;
124 bool hasALoadOrStore : 1;
128 hasSubelementAccess(
false), hasALoadOrStore(
false) {}
132 unsigned SRThreshold;
136 unsigned StructMemberThreshold;
140 unsigned ArrayElementThreshold;
144 unsigned ScalarLoadThreshold;
148 DEBUG(
dbgs() <<
" Transformation preventing inst: " << *User <<
'\n');
151 bool isSafeAllocaToScalarRepl(
AllocaInst *AI);
153 void isSafeForScalarRepl(
Instruction *I, uint64_t Offset, AllocaInfo &Info);
154 void isSafePHISelectUseForScalarRepl(
Instruction *User, uint64_t Offset,
157 void isSafeMemAccess(uint64_t Offset, uint64_t MemSize,
158 Type *MemOpType,
bool isStore, AllocaInfo &Info,
160 bool TypeHasComponent(
Type *T, uint64_t Offset, uint64_t Size);
161 uint64_t FindElementAndOffset(
Type *&T, uint64_t &Offset,
165 std::vector<AllocaInst*> &WorkList);
166 void DeleteDeadInstructions();
188 struct SROA_DT :
public SROA {
191 SROA_DT(
int T = -1,
int ST = -1,
int AT = -1,
int SLT = -1) :
192 SROA(T,
true, ID, ST, AT, SLT) {
205 struct SROA_SSAUp :
public SROA {
208 SROA_SSAUp(
int T = -1,
int ST = -1,
int AT = -1,
int SLT = -1) :
209 SROA(T,
false, ID, ST, AT, SLT) {
226 "Scalar Replacement of Aggregates (DT)",
false,
false)
239 int StructMemberThreshold,
240 int ArrayElementThreshold,
241 int ScalarLoadThreshold) {
243 return new SROA_DT(Threshold, StructMemberThreshold, ArrayElementThreshold,
244 ScalarLoadThreshold);
245 return new SROA_SSAUp(Threshold, StructMemberThreshold,
246 ArrayElementThreshold, ScalarLoadThreshold);
258 class ConvertToScalarInfo {
262 unsigned ScalarLoadThreshold;
296 bool HadNonMemTransferAccess;
301 bool HadDynamicAccess;
304 explicit ConvertToScalarInfo(
unsigned Size,
const DataLayout &td,
306 : AllocaSize(Size),
TD(td), ScalarLoadThreshold(SLT), IsNotTrivial(
false),
307 ScalarKind(
Unknown), VectorTy(0), HadNonMemTransferAccess(
false),
308 HadDynamicAccess(
false) { }
313 bool CanConvertToScalar(
Value *V, uint64_t Offset,
Value* NonConstantIdx);
314 void MergeInTypeForLoadOrStore(
Type *
In, uint64_t Offset);
315 bool MergeInVectorType(
VectorType *VInTy, uint64_t Offset);
316 void ConvertUsesToScalar(
Value *Ptr,
AllocaInst *NewAI, uint64_t Offset,
317 Value *NonConstantIdx);
320 uint64_t Offset,
Value* NonConstantIdx,
323 uint64_t Offset,
Value* NonConstantIdx,
335 if (!CanConvertToScalar(AI, 0, 0) || !IsNotTrivial)
341 ScalarKind = Integer;
343 if (ScalarKind == Vector && VectorTy->getBitWidth() != AllocaSize * 8)
344 ScalarKind = Integer;
353 if (ScalarKind == Vector) {
354 assert(VectorTy &&
"Missing type for vector scalar.");
355 DEBUG(
dbgs() <<
"CONVERT TO VECTOR: " << *AI <<
"\n TYPE = "
356 << *VectorTy <<
'\n');
359 unsigned BitWidth = AllocaSize * 8;
363 if (BitWidth > ScalarLoadThreshold)
366 if ((ScalarKind == ImplicitVector || ScalarKind == Integer) &&
367 !HadNonMemTransferAccess && !
TD.fitsInLegalInteger(BitWidth))
372 if (ScalarKind == Integer && HadDynamicAccess)
375 DEBUG(
dbgs() <<
"CONVERT TO SCALAR INTEGER: " << *AI <<
"\n");
380 ConvertUsesToScalar(AI, NewAI, 0, 0);
397 void ConvertToScalarInfo::MergeInTypeForLoadOrStore(
Type *
In,
401 if (ScalarKind == Integer)
408 if (
VectorType *VInTy = dyn_cast<VectorType>(In)) {
409 if (MergeInVectorType(VInTy, Offset))
417 if (EltSize == AllocaSize)
423 if (Offset % EltSize == 0 && AllocaSize % EltSize == 0 &&
424 (!VectorTy || EltSize == VectorTy->getElementType()
425 ->getPrimitiveSizeInBits()/8)) {
427 ScalarKind = ImplicitVector;
436 ScalarKind = Integer;
441 bool ConvertToScalarInfo::MergeInVectorType(
VectorType *VInTy,
443 if (VInTy->
getBitWidth()/8 == AllocaSize && Offset == 0) {
467 bool ConvertToScalarInfo::CanConvertToScalar(
Value *V, uint64_t Offset,
468 Value* NonConstantIdx) {
472 if (
LoadInst *
LI = dyn_cast<LoadInst>(User)) {
477 if (
LI->getType()->isX86_MMXTy())
479 HadNonMemTransferAccess =
true;
480 MergeInTypeForLoadOrStore(
LI->getType(), Offset);
484 if (
StoreInst *SI = dyn_cast<StoreInst>(User)) {
486 if (SI->getOperand(0) == V || !SI->isSimple())
return false;
488 if (SI->getOperand(0)->getType()->isX86_MMXTy())
490 HadNonMemTransferAccess =
true;
491 MergeInTypeForLoadOrStore(SI->getOperand(0)->getType(), Offset);
495 if (
BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
498 if (!CanConvertToScalar(BCI, Offset, NonConstantIdx))
511 Value *GEPNonConstantIdx = 0;
512 if (!GEP->hasAllConstantIndices()) {
518 if (!GEPNonConstantIdx->getType()->isIntegerTy(32))
520 HadDynamicAccess =
true;
522 GEPNonConstantIdx = NonConstantIdx;
523 uint64_t GEPOffset =
TD.getIndexedOffset(PtrTy,
526 if (!CanConvertToScalar(GEP, Offset+GEPOffset, GEPNonConstantIdx))
529 HadNonMemTransferAccess =
true;
535 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
540 if (!isa<ConstantInt>(MSI->getValue()))
553 ScalarKind = Integer;
556 HadNonMemTransferAccess =
true;
567 if (Len == 0 || Len->
getZExtValue() != AllocaSize || Offset != 0)
596 void ConvertToScalarInfo::ConvertUsesToScalar(
Value *Ptr,
AllocaInst *NewAI,
598 Value* NonConstantIdx) {
602 if (
BitCastInst *CI = dyn_cast<BitCastInst>(User)) {
603 ConvertUsesToScalar(CI, NewAI, Offset, NonConstantIdx);
604 CI->eraseFromParent();
611 Value* GEPNonConstantIdx = 0;
612 if (!GEP->hasAllConstantIndices()) {
613 assert(!NonConstantIdx &&
614 "Dynamic GEP reading from dynamic GEP unsupported");
617 GEPNonConstantIdx = NonConstantIdx;
618 uint64_t GEPOffset =
TD.getIndexedOffset(GEP->getPointerOperandType(),
620 ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8, GEPNonConstantIdx);
621 GEP->eraseFromParent();
627 if (
LoadInst *
LI = dyn_cast<LoadInst>(User)) {
629 Value *LoadedVal = Builder.CreateLoad(NewAI);
631 = ConvertScalar_ExtractValue(LoadedVal,
LI->getType(), Offset,
632 NonConstantIdx, Builder);
633 LI->replaceAllUsesWith(NewLoadVal);
634 LI->eraseFromParent();
638 if (
StoreInst *SI = dyn_cast<StoreInst>(User)) {
639 assert(SI->getOperand(0) != Ptr &&
"Consistency error!");
641 Value *New = ConvertScalar_InsertValue(SI->getOperand(0), Old, Offset,
642 NonConstantIdx, Builder);
643 Builder.CreateStore(New, NewAI);
644 SI->eraseFromParent();
648 if (Old->use_empty())
649 Old->eraseFromParent();
655 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
656 assert(MSI->getRawDest() == Ptr &&
"Consistency error!");
657 assert(!NonConstantIdx &&
"Cannot replace dynamic memset with insert");
658 int64_t SNumBytes = cast<ConstantInt>(MSI->getLength())->getSExtValue();
659 if (SNumBytes > 0 && (SNumBytes >> 32) == 0) {
660 unsigned NumBytes =
static_cast<unsigned>(SNumBytes);
661 unsigned Val = cast<ConstantInt>(MSI->getValue())->getZExtValue();
664 APInt APVal(NumBytes*8, Val);
668 for (
unsigned i = 1; i != NumBytes; ++i)
672 Value *New = ConvertScalar_InsertValue(
674 Old, Offset, 0, Builder);
675 Builder.CreateStore(New, NewAI);
682 MSI->eraseFromParent();
689 assert(Offset == 0 &&
"must be store to start of alloca");
690 assert(!NonConstantIdx &&
"Cannot replace dynamic transfer with insert");
700 assert(MTI->getRawDest() == Ptr &&
"Neither use is of pointer?");
701 Value *SrcPtr = MTI->getSource();
702 PointerType* SPTy = cast<PointerType>(SrcPtr->getType());
708 SrcPtr = Builder.CreateBitCast(SrcPtr, AIPTy);
710 LoadInst *SrcVal = Builder.CreateLoad(SrcPtr,
"srcval");
712 Builder.CreateStore(SrcVal, NewAI);
716 assert(MTI->getRawSource() == Ptr &&
"Neither use is of pointer?");
717 LoadInst *SrcVal = Builder.CreateLoad(NewAI,
"srcval");
719 PointerType* DPTy = cast<PointerType>(MTI->getDest()->getType());
725 Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), AIPTy);
727 StoreInst *NewStore = Builder.CreateStore(SrcVal, DstPtr);
733 MTI->eraseFromParent();
742 II->eraseFromParent();
761 Value *ConvertToScalarInfo::
762 ConvertScalar_ExtractValue(
Value *FromVal,
Type *ToType,
763 uint64_t Offset,
Value* NonConstantIdx,
767 if (FromType == ToType && Offset == 0)
772 if (
VectorType *VTy = dyn_cast<VectorType>(FromType)) {
773 unsigned FromTypeSize =
TD.getTypeAllocSize(FromType);
774 unsigned ToTypeSize =
TD.getTypeAllocSize(ToType);
775 if (FromTypeSize == ToTypeSize)
781 unsigned EltSize =
TD.getTypeAllocSizeInBits(VTy->getElementType());
782 Elt = Offset/EltSize;
783 assert(EltSize*Elt == Offset &&
"Invalid modulus in validity checking");
787 if (NonConstantIdx) {
793 Idx = NonConstantIdx;
804 if (
StructType *ST = dyn_cast<StructType>(ToType)) {
805 assert(!NonConstantIdx &&
806 "Dynamic indexing into struct types not supported");
809 for (
unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
810 Value *Elt = ConvertScalar_ExtractValue(FromVal, ST->getElementType(i),
818 if (
ArrayType *AT = dyn_cast<ArrayType>(ToType)) {
819 assert(!NonConstantIdx &&
820 "Dynamic indexing into array types not supported");
821 uint64_t EltSize =
TD.getTypeAllocSizeInBits(AT->getElementType());
823 for (
unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
824 Value *Elt = ConvertScalar_ExtractValue(FromVal, AT->getElementType(),
825 Offset+i*EltSize, 0, Builder);
837 if (
TD.isBigEndian()) {
841 ShAmt =
TD.getTypeStoreSizeInBits(NTy) -
842 TD.getTypeStoreSizeInBits(ToType) - Offset;
850 if (ShAmt > 0 && (
unsigned)ShAmt < NTy->
getBitWidth())
853 else if (ShAmt < 0 && (
unsigned)-ShAmt < NTy->
getBitWidth())
858 unsigned LIBitWidth =
TD.getTypeSizeInBits(ToType);
878 assert(FromVal->
getType() == ToType &&
"Didn't convert right?");
895 Value *ConvertToScalarInfo::
896 ConvertScalar_InsertValue(
Value *SV,
Value *Old,
897 uint64_t Offset,
Value* NonConstantIdx,
904 if (
VectorType *VTy = dyn_cast<VectorType>(AllocaType)) {
905 uint64_t VecSize =
TD.getTypeAllocSizeInBits(VTy);
906 uint64_t ValSize =
TD.getTypeAllocSizeInBits(SV->
getType());
910 if (ValSize == VecSize)
914 Type *EltTy = VTy->getElementType();
917 uint64_t EltSize =
TD.getTypeAllocSizeInBits(EltTy);
918 unsigned Elt = Offset/EltSize;
920 if (NonConstantIdx) {
926 Idx = NonConstantIdx;
934 assert(!NonConstantIdx &&
935 "Dynamic indexing into struct types not supported");
937 for (
unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
939 Old = ConvertScalar_InsertValue(Elt, Old,
947 assert(!NonConstantIdx &&
948 "Dynamic indexing into array types not supported");
949 uint64_t EltSize =
TD.getTypeAllocSizeInBits(AT->getElementType());
950 for (
unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
952 Old = ConvertScalar_InsertValue(Elt, Old, Offset+i*EltSize, 0, Builder);
959 unsigned SrcWidth =
TD.getTypeSizeInBits(SV->
getType());
960 unsigned DestWidth =
TD.getTypeSizeInBits(AllocaType);
961 unsigned SrcStoreWidth =
TD.getTypeStoreSizeInBits(SV->
getType());
962 unsigned DestStoreWidth =
TD.getTypeStoreSizeInBits(AllocaType);
969 if (SV->
getType() != AllocaType) {
977 SrcWidth = DestWidth;
978 SrcStoreWidth = DestStoreWidth;
985 if (
TD.isBigEndian()) {
989 ShAmt = DestStoreWidth - SrcStoreWidth - Offset;
998 if (ShAmt > 0 && (
unsigned)ShAmt < DestWidth) {
1001 }
else if (ShAmt < 0 && (
unsigned)-ShAmt < DestWidth) {
1003 Mask = Mask.lshr(-ShAmt);
1008 if (SrcWidth != DestWidth) {
1009 assert(DestWidth > SrcWidth);
1011 SV = Builder.
CreateOr(Old, SV,
"ins");
1023 TD = getAnalysisIfAvailable<DataLayout>();
1025 bool Changed = performPromotion(F);
1031 if (!
TD)
return Changed;
1034 bool LocalChange = performScalarRepl(F);
1035 if (!LocalChange)
break;
1037 LocalChange = performPromotion(F);
1038 if (!LocalChange)
break;
1060 E = DebugNode->use_end(); UI != E; ++UI)
1062 DDIs.push_back(DDI);
1063 else if (
DbgValueInst *DVI = dyn_cast<DbgValueInst>(*UI))
1064 DVIs.push_back(DVI);
1070 E = DDIs.end();
I != E; ++
I) {
1075 E = DVIs.end();
I != E; ++
I) {
1084 return LI->getOperand(0) == AI;
1088 virtual void updateDebugInfo(
Instruction *Inst)
const {
1090 E = DDIs.end(); I != E; ++
I) {
1092 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst))
1094 else if (
LoadInst *
LI = dyn_cast<LoadInst>(Inst))
1098 E = DVIs.end(); I != E; ++
I) {
1101 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
1104 if (
ZExtInst *ZExt = dyn_cast<ZExtInst>(SI->getOperand(0)))
1106 if (
SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))
1109 Arg = SI->getOperand(0);
1110 }
else if (
LoadInst *
LI = dyn_cast<LoadInst>(Inst)) {
1111 Arg =
LI->getOperand(0);
1144 if (LI == 0 || !LI->
isSimple())
return false;
1181 unsigned MaxAlign = 0;
1185 if (LI == 0 || !LI->
isSimple())
return false;
1189 if (LI->
getParent() != BB)
return false;
1194 if (BBI->mayWriteToMemory())
1247 if (!
LI->isSimple())
1252 if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
1253 if (SI->getOperand(0) == AI || !SI->isSimple())
1258 if (
SelectInst *SI = dyn_cast<SelectInst>(U)) {
1261 if (
ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition())) {
1262 Value *Result = SI->getOperand(1+CI->isZero());
1264 SI->eraseFromParent();
1276 InstsToRewrite.
insert(SI);
1280 if (
PHINode *PN = dyn_cast<PHINode>(U)) {
1281 if (PN->use_empty()) {
1282 InstsToRewrite.
insert(PN);
1291 InstsToRewrite.
insert(PN);
1295 if (
BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
1297 InstsToRewrite.
insert(BCI);
1307 if (InstsToRewrite.
empty())
1312 for (
unsigned i = 0, e = InstsToRewrite.
size(); i != e; ++i) {
1313 if (
BitCastInst *BCI = dyn_cast<BitCastInst>(InstsToRewrite[i])) {
1317 Use &U = I.getUse();
1319 cast<Instruction>(U.
getUser())->eraseFromParent();
1321 BCI->eraseFromParent();
1325 if (
SelectInst *SI = dyn_cast<SelectInst>(InstsToRewrite[i])) {
1328 while (!SI->use_empty()) {
1329 LoadInst *
LI = cast<LoadInst>(SI->use_back());
1333 Builder.CreateLoad(SI->getTrueValue(), LI->
getName()+
".t");
1335 Builder.CreateLoad(SI->getFalseValue(), LI->
getName()+
".f");
1345 Value *V = Builder.CreateSelect(SI->getCondition(), TrueLoad, FalseLoad);
1352 SI->eraseFromParent();
1358 PHINode *PN = cast<PHINode>(InstsToRewrite[i]);
1364 Type *LoadTy = cast<PointerType>(PN->
getType())->getElementType();
1372 unsigned Align = SomeLoad->getAlignment();
1406 bool SROA::performPromotion(
Function &F) {
1407 std::vector<AllocaInst*> Allocas;
1410 DT = &getAnalysis<DominatorTree>();
1414 bool Changed =
false;
1422 if (
AllocaInst *AI = dyn_cast<AllocaInst>(I))
1424 Allocas.push_back(AI);
1426 if (Allocas.empty())
break;
1432 for (
unsigned i = 0, e = Allocas.size(); i != e; ++i) {
1438 Insts.
push_back(cast<Instruction>(*UI));
1439 AllocaPromoter(Insts, SSA, &DIB).run(AI, Insts);
1443 NumPromoted += Allocas.size();
1453 bool SROA::ShouldAttemptScalarRepl(
AllocaInst *AI) {
1456 if (
StructType *ST = dyn_cast<StructType>(T))
1457 return ST->getNumElements() <= StructMemberThreshold;
1459 if (
ArrayType *AT = dyn_cast<ArrayType>(T))
1460 return AT->getNumElements() <= ArrayElementThreshold;
1468 bool SROA::performScalarRepl(
Function &F) {
1469 std::vector<AllocaInst*> WorkList;
1475 WorkList.push_back(
A);
1478 bool Changed =
false;
1479 while (!WorkList.empty()) {
1481 WorkList.pop_back();
1502 if (AllocaSize == 0)
continue;
1505 if (AllocaSize > SRThreshold)
continue;
1510 if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) {
1511 DoScalarReplacement(AI, WorkList);
1523 (
unsigned)AllocaSize, *
TD, ScalarLoadThreshold).TryConvert(AI)) {
1539 void SROA::DoScalarReplacement(
AllocaInst *AI,
1540 std::vector<AllocaInst*> &WorkList) {
1541 DEBUG(
dbgs() <<
"Found inst to SROA: " << *AI <<
'\n');
1544 ElementAllocas.
reserve(ST->getNumContainedTypes());
1545 for (
unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
1550 WorkList.push_back(NA);
1560 WorkList.push_back(NA);
1566 RewriteForScalarRepl(AI, AI, 0, ElementAllocas);
1569 DeleteDeadInstructions();
1577 void SROA::DeleteDeadInstructions() {
1578 while (!DeadInsts.empty()) {
1579 Instruction *I = cast<Instruction>(DeadInsts.pop_back_val());
1582 if (
Instruction *U = dyn_cast<Instruction>(*OI)) {
1588 DeadInsts.push_back(U);
1599 void SROA::isSafeForScalarRepl(
Instruction *I, uint64_t Offset,
1604 if (
BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
1605 isSafeForScalarRepl(BC, Offset, Info);
1607 uint64_t GEPOffset = Offset;
1608 isSafeGEP(GEPI, GEPOffset, Info);
1610 isSafeForScalarRepl(GEPI, GEPOffset, Info);
1614 return MarkUnsafe(Info, User);
1616 return MarkUnsafe(Info, User);
1619 UI.getOperandNo() == 0, Info,
MI,
1621 }
else if (
LoadInst *
LI = dyn_cast<LoadInst>(User)) {
1622 if (!
LI->isSimple())
1623 return MarkUnsafe(Info, User);
1624 Type *LIType =
LI->getType();
1625 isSafeMemAccess(Offset,
TD->getTypeAllocSize(LIType),
1626 LIType,
false, Info,
LI,
true );
1627 Info.hasALoadOrStore =
true;
1629 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(User)) {
1631 if (!SI->isSimple() || SI->getOperand(0) ==
I)
1632 return MarkUnsafe(Info, User);
1634 Type *SIType = SI->getOperand(0)->getType();
1635 isSafeMemAccess(Offset,
TD->getTypeAllocSize(SIType),
1636 SIType,
true, Info, SI,
true );
1637 Info.hasALoadOrStore =
true;
1638 }
else if (
IntrinsicInst *II = dyn_cast<IntrinsicInst>(User)) {
1641 return MarkUnsafe(Info, User);
1642 }
else if (isa<PHINode>(User) || isa<SelectInst>(User)) {
1643 isSafePHISelectUseForScalarRepl(User, Offset, Info);
1645 return MarkUnsafe(Info, User);
1647 if (Info.isUnsafe)
return;
1661 void SROA::isSafePHISelectUseForScalarRepl(
Instruction *I, uint64_t Offset,
1664 if (
PHINode *PN = dyn_cast<PHINode>(I))
1665 if (!Info.CheckedPHIs.insert(PN))
1671 if (
BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
1672 isSafePHISelectUseForScalarRepl(BC, Offset, Info);
1677 if (!GEPI->hasAllZeroIndices())
1678 return MarkUnsafe(Info, User);
1679 isSafePHISelectUseForScalarRepl(GEPI, Offset, Info);
1680 }
else if (
LoadInst *
LI = dyn_cast<LoadInst>(User)) {
1681 if (!
LI->isSimple())
1682 return MarkUnsafe(Info, User);
1683 Type *LIType =
LI->getType();
1684 isSafeMemAccess(Offset,
TD->getTypeAllocSize(LIType),
1685 LIType,
false, Info,
LI,
false );
1686 Info.hasALoadOrStore =
true;
1688 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(User)) {
1690 if (!SI->isSimple() || SI->getOperand(0) ==
I)
1691 return MarkUnsafe(Info, User);
1693 Type *SIType = SI->getOperand(0)->getType();
1694 isSafeMemAccess(Offset,
TD->getTypeAllocSize(SIType),
1695 SIType,
true, Info, SI,
false );
1696 Info.hasALoadOrStore =
true;
1697 }
else if (isa<PHINode>(User) || isa<SelectInst>(User)) {
1698 isSafePHISelectUseForScalarRepl(User, Offset, Info);
1700 return MarkUnsafe(Info, User);
1702 if (Info.isUnsafe)
return;
1712 uint64_t &Offset, AllocaInfo &Info) {
1716 bool NonConstant =
false;
1717 unsigned NonConstantIdxSize = 0;
1721 for (; GEPIt != E; ++GEPIt) {
1723 if ((*GEPIt)->isStructTy())
1728 return MarkUnsafe(Info, GEPI);
1740 if (!TypeHasComponent(Info.AI->getAllocatedType(), Offset,
1741 NonConstantIdxSize))
1742 MarkUnsafe(Info, GEPI);
1751 if (
ArrayType *AT = dyn_cast<ArrayType>(T)) {
1756 if (
StructType *ST = dyn_cast<StructType>(T)) {
1757 NumElts = ST->getNumContainedTypes();
1758 EltTy = (NumElts == 0 ? 0 : ST->getContainedType(0));
1759 for (
unsigned n = 1; n < NumElts; ++n) {
1760 if (ST->getContainedType(n) != EltTy)
1774 unsigned NumElts1, NumElts2;
1775 Type *EltTy1, *EltTy2;
1778 NumElts1 == NumElts2 &&
1792 void SROA::isSafeMemAccess(uint64_t Offset, uint64_t MemSize,
1793 Type *MemOpType,
bool isStore,
1795 bool AllowWholeAccess) {
1797 if (Offset == 0 && AllowWholeAccess &&
1798 MemSize ==
TD->getTypeAllocSize(Info.AI->getAllocatedType())) {
1806 Info.isMemCpyDst =
true;
1808 Info.isMemCpySrc =
true;
1815 Info.hasSubelementAccess =
true;
1820 Type *T = Info.AI->getAllocatedType();
1821 if (TypeHasComponent(T, Offset, MemSize)) {
1822 Info.hasSubelementAccess =
true;
1826 return MarkUnsafe(Info, TheAccess);
1831 bool SROA::TypeHasComponent(
Type *T, uint64_t Offset, uint64_t Size) {
1834 if (
StructType *ST = dyn_cast<StructType>(T)) {
1838 EltSize =
TD->getTypeAllocSize(EltTy);
1840 }
else if (
ArrayType *AT = dyn_cast<ArrayType>(T)) {
1842 EltSize =
TD->getTypeAllocSize(EltTy);
1846 }
else if (
VectorType *VT = dyn_cast<VectorType>(T)) {
1847 EltTy = VT->getElementType();
1848 EltSize =
TD->getTypeAllocSize(EltTy);
1849 if (Offset >= VT->getNumElements() * EltSize)
1855 if (Offset == 0 && (Size == 0 || EltSize == Size))
1858 if (Offset + Size > EltSize)
1860 return TypeHasComponent(EltTy, Offset, Size);
1870 Use &TheUse = UI.getUse();
1873 if (
BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
1874 RewriteBitCast(BC, AI, Offset, NewElts);
1879 RewriteGEP(GEPI, AI, Offset, NewElts);
1888 RewriteMemIntrinUserOfAlloca(
MI, I, AI, NewElts);
1897 RewriteLifetimeIntrinsic(II, AI, Offset, NewElts);
1902 if (
LoadInst *
LI = dyn_cast<LoadInst>(User)) {
1903 Type *LIType =
LI->getType();
1916 for (
unsigned i = 0, e = NewElts.
size(); i != e; ++i) {
1920 LI->replaceAllUsesWith(Insert);
1921 DeadInsts.push_back(
LI);
1923 TD->getTypeAllocSize(LIType) ==
1926 RewriteLoadUserOfWholeAlloca(
LI, AI, NewElts);
1931 if (
StoreInst *SI = dyn_cast<StoreInst>(User)) {
1932 Value *Val = SI->getOperand(0);
1944 for (
unsigned i = 0, e = NewElts.
size(); i != e; ++i) {
1948 DeadInsts.push_back(SI);
1950 TD->getTypeAllocSize(SIType) ==
1953 RewriteStoreUserOfWholeAlloca(SI, AI, NewElts);
1958 if (isa<SelectInst>(User) || isa<PHINode>(User)) {
1962 if (!isa<AllocaInst>(I))
continue;
1964 assert(Offset == 0 && NewElts[0] &&
1965 "Direct alloca use should have a zero offset");
1983 RewriteForScalarRepl(BC, AI, Offset, NewElts);
1992 uint64_t EltOffset = 0;
1994 uint64_t Idx = FindElementAndOffset(T, EltOffset, IdxTy);
2001 DeadInsts.push_back(BC);
2009 uint64_t SROA::FindElementAndOffset(
Type *&T, uint64_t &Offset,
2012 if (
StructType *ST = dyn_cast<StructType>(T)) {
2019 }
else if (
ArrayType *AT = dyn_cast<ArrayType>(T)) {
2021 uint64_t EltSize =
TD->getTypeAllocSize(T);
2022 Idx = Offset / EltSize;
2023 Offset -= Idx * EltSize;
2029 uint64_t EltSize =
TD->getTypeAllocSize(T);
2030 Idx = Offset / EltSize;
2031 Offset -= Idx * EltSize;
2041 uint64_t OldOffset = Offset;
2047 Value* NonConstantIdx = 0;
2052 RewriteForScalarRepl(GEPI, AI, Offset, NewElts);
2056 uint64_t OldIdx = FindElementAndOffset(T, OldOffset, IdxTy);
2061 uint64_t EltOffset = Offset;
2062 uint64_t Idx = FindElementAndOffset(T, EltOffset, IdxTy);
2072 while (EltOffset != 0) {
2073 uint64_t EltIdx = FindElementAndOffset(T, EltOffset, IdxTy);
2076 if (NonConstantIdx) {
2081 while (!isa<VectorType>(GepTy)) {
2083 GepTy = cast<CompositeType>(GepTy)->getTypeAtIndex(0U);
2085 NewArgs.push_back(NonConstantIdx);
2088 if (NewArgs.size() > 1) {
2095 DeadInsts.push_back(GEPI);
2107 uint64_t NewOffset = Offset;
2109 uint64_t Idx = FindElementAndOffset(AIType, NewOffset, IdxTy);
2120 IdxTy = NewElts[Idx]->getAllocatedType();
2121 uint64_t EltSize =
TD->getTypeAllocSize(IdxTy) - NewOffset;
2122 if (EltSize > Size) {
2135 for (; Idx != NewElts.
size() && Size; ++Idx) {
2136 IdxTy = NewElts[Idx]->getAllocatedType();
2137 uint64_t EltSize =
TD->getTypeAllocSize(IdxTy);
2138 if (EltSize > Size) {
2151 DeadInsts.push_back(II);
2164 Value *OtherPtr = 0;
2167 if (Inst == MTI->getRawDest())
2168 OtherPtr = MTI->getRawSource();
2170 assert(Inst == MTI->getRawSource());
2171 OtherPtr = MTI->getRawDest();
2178 unsigned AddrSpace =
2179 cast<PointerType>(OtherPtr->
getType())->getAddressSpace();
2190 if (OtherPtr == AI || OtherPtr == NewElts[0]) {
2194 E = DeadInsts.end(); I != E; ++
I)
2195 if (*I == MI)
return;
2196 DeadInsts.push_back(MI);
2205 if (OtherPtr->
getType() != NewTy)
2214 for (
unsigned i = 0, e = NewElts.
size(); i != e; ++i) {
2216 Value *OtherElt = 0;
2217 unsigned OtherEltAlign = MemAlignment;
2220 Value *Idx[2] = { Zero,
2228 if (
StructType *ST = dyn_cast<StructType>(OtherTy)) {
2229 EltOffset =
TD->getStructLayout(ST)->getElementOffset(i);
2231 Type *EltTy = cast<SequentialType>(OtherTy)->getElementType();
2232 EltOffset =
TD->getTypeAllocSize(EltTy)*i;
2243 Value *EltPtr = NewElts[i];
2244 Type *EltTy = cast<PointerType>(EltPtr->
getType())->getElementType();
2248 if (isa<MemTransferInst>(MI)) {
2251 Value *Elt =
new LoadInst(OtherElt,
"tmp",
false, OtherEltAlign, MI);
2256 new StoreInst(Elt, OtherElt,
false, OtherEltAlign, MI);
2260 assert(isa<MemSetInst>(MI));
2273 unsigned EltSize =
TD->getTypeSizeInBits(ValTy);
2274 APInt OneVal(EltSize, CI->getZExtValue());
2275 APInt TotalVal(OneVal);
2277 for (
unsigned i = 0; 8*i < EltSize; ++i) {
2278 TotalVal = TotalVal.shl(8);
2288 assert(StoreVal->
getType() == ValTy &&
"Type mismatch!");
2292 unsigned NumElts = cast<VectorType>(EltTy)->getNumElements();
2303 unsigned EltSize =
TD->getTypeAllocSize(EltTy);
2310 if (isa<MemSetInst>(MI)) {
2314 assert(isa<MemTransferInst>(MI));
2315 Value *Dst = SROADest ? EltPtr : OtherElt;
2316 Value *Src = SROADest ? OtherElt : EltPtr;
2318 if (isa<MemCpyInst>(MI))
2324 DeadInsts.push_back(MI);
2337 uint64_t AllocaSizeBits =
TD->getTypeAllocSizeInBits(AllocaEltTy);
2342 if (
TD->getTypeSizeInBits(SrcVal->
getType()) != AllocaSizeBits)
2346 DEBUG(
dbgs() <<
"PROMOTING STORE TO WHOLE ALLOCA: " << *AI <<
'\n' << *SI
2351 if (
StructType *EltSTy = dyn_cast<StructType>(AllocaEltTy)) {
2354 for (
unsigned i = 0, e = NewElts.
size(); i != e; ++i) {
2356 Type *FieldTy = EltSTy->getElementType(i);
2359 if (
TD->isBigEndian())
2360 Shift = AllocaSizeBits-Shift-
TD->getTypeAllocSizeInBits(FieldTy);
2362 Value *EltVal = SrcVal;
2365 EltVal = Builder.
CreateLShr(EltVal, ShiftVal,
"sroa.store.elt");
2369 uint64_t FieldSizeBits =
TD->getTypeSizeInBits(FieldTy);
2372 if (FieldSizeBits == 0)
continue;
2374 if (FieldSizeBits != AllocaSizeBits)
2377 Value *DestField = NewElts[i];
2378 if (EltVal->getType() == FieldTy) {
2392 ArrayType *ATy = cast<ArrayType>(AllocaEltTy);
2394 uint64_t ElementOffset =
TD->getTypeAllocSizeInBits(ArrayEltTy);
2395 uint64_t ElementSizeBits =
TD->getTypeSizeInBits(ArrayEltTy);
2399 if (
TD->isBigEndian())
2400 Shift = AllocaSizeBits-ElementOffset;
2404 for (
unsigned i = 0, e = NewElts.
size(); i != e; ++i) {
2406 if (ElementSizeBits == 0)
continue;
2408 Value *EltVal = SrcVal;
2411 EltVal = Builder.
CreateLShr(EltVal, ShiftVal,
"sroa.store.elt");
2415 if (ElementSizeBits != AllocaSizeBits)
2419 Value *DestField = NewElts[i];
2420 if (EltVal->getType() == ArrayEltTy) {
2422 }
else if (ArrayEltTy->isFloatingPointTy() ||
2423 ArrayEltTy->isVectorTy()) {
2433 if (
TD->isBigEndian())
2434 Shift -= ElementOffset;
2436 Shift += ElementOffset;
2440 DeadInsts.push_back(SI);
2451 uint64_t AllocaSizeBits =
TD->getTypeAllocSizeInBits(AllocaEltTy);
2453 DEBUG(
dbgs() <<
"PROMOTING LOAD OF WHOLE ALLOCA: " << *AI <<
'\n' << *LI
2459 uint64_t ArrayEltBitOffset = 0;
2460 if (
StructType *EltSTy = dyn_cast<StructType>(AllocaEltTy)) {
2461 Layout =
TD->getStructLayout(EltSTy);
2463 Type *ArrayEltTy = cast<ArrayType>(AllocaEltTy)->getElementType();
2464 ArrayEltBitOffset =
TD->getTypeAllocSizeInBits(ArrayEltTy);
2470 for (
unsigned i = 0, e = NewElts.
size(); i != e; ++i) {
2473 Value *SrcField = NewElts[i];
2475 cast<PointerType>(SrcField->
getType())->getElementType();
2476 uint64_t FieldSizeBits =
TD->getTypeSizeInBits(FieldTy);
2479 if (FieldSizeBits == 0)
continue;
2488 SrcField =
new LoadInst(SrcField,
"sroa.load.elt", LI);
2492 if (SrcField->
getType() != FieldIntTy)
2493 SrcField =
new BitCastInst(SrcField, FieldIntTy,
"", LI);
2505 Shift = i*ArrayEltBitOffset;
2507 if (
TD->isBigEndian())
2508 Shift = AllocaSizeBits-Shift-FieldIntTy->
getBitWidth();
2512 SrcField = BinaryOperator::CreateShl(SrcField, ShiftVal,
"", LI);
2516 if (!isa<Constant>(ResultVal) ||
2517 !cast<Constant>(ResultVal)->isNullValue())
2518 ResultVal = BinaryOperator::CreateOr(SrcField, ResultVal,
"", LI);
2520 ResultVal = SrcField;
2524 if (
TD->getTypeSizeInBits(LI->
getType()) != AllocaSizeBits)
2528 DeadInsts.push_back(LI);
2535 if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
2543 unsigned PrevFieldBitOffset = 0;
2550 unsigned PrevFieldEnd =
2552 if (PrevFieldEnd < FieldBitOffset)
2555 PrevFieldBitOffset = FieldBitOffset;
2559 unsigned PrevFieldEnd = PrevFieldBitOffset +
2561 if (PrevFieldEnd < SL->getSizeInBits())
2570 bool SROA::isSafeAllocaToScalarRepl(
AllocaInst *AI) {
2573 AllocaInfo Info(AI);
2575 isSafeForScalarRepl(AI, 0, Info);
2576 if (Info.isUnsafe) {
2577 DEBUG(
dbgs() <<
"Cannot transform: " << *AI <<
'\n');
2586 if (Info.isMemCpySrc && Info.isMemCpyDst &&
2594 if (!Info.hasSubelementAccess && Info.hasALoadOrStore) {
2597 if (ST->getNumElements() > 1)
return false;
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
unsigned getAlignment() const
Value * CreateGEP(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
void push_back(const T &Elt)
Helper class for SSA formation on a set of values defined in multiple blocks.
LoadInst * CreateLoad(Value *Ptr, const char *Name)
void addIncoming(Value *V, BasicBlock *BB)
static PassRegistry * getPassRegistry()
LLVM Argument representation.
FunctionPass * createScalarReplAggregatesPass(signed Threshold=-1, bool UseDomTree=true, signed StructMemberThreshold=-1, signed ArrayElementThreshold=-1, signed ScalarLoadThreshold=-1)
STATISTIC(NumReplaced,"Number of allocas broken up")
Intrinsic::ID getIntrinsicID() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
This class represents zero extension of integer types.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
gep_type_iterator gep_type_end(const User *GEP)
bool mayHaveSideEffects() const
bool isDoubleTy() const
isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
MDNode - a tuple of other values.
void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AliasSetTracker *AST=0)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, unsigned Align, const DataLayout *TD=0)
This class represents a sign extension of integer types.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
static IntegerType * getInt64Ty(LLVMContext &C)
void setDebugLoc(const DebugLoc &Loc)
setDebugLoc - Set the debug location information for this instruction.
size_type size() const
Determine the number of elements in the SetVector.
void initializeSROA_DTPass(PassRegistry &)
CallInst * CreateLifetimeEnd(Value *Ptr, ConstantInt *Size=0)
Create a lifetime.end intrinsic.
LoopInfoBase< BlockT, LoopT > * LI
uint64_t getTypeAllocSizeInBits(Type *Ty) const
Value * CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, const Twine &Name="")
static Constant * getNullValue(Type *Ty)
StringRef getName() const
bool isSingleValueType() const
bool isArrayAllocation() const
Scalar Replacement of Aggregates(DT)"
CallInst * CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=0)
Create and insert a memmove between the specified pointers.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * GetUnderlyingObject(Value *V, const DataLayout *TD=0, unsigned MaxLookup=6)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static Value * getPointerOperand(Instruction &Inst)
static unsigned getBitWidth(Type *Ty, const DataLayout *TD)
const StructLayout * getStructLayout(StructType *Ty) const
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
unsigned getBitWidth() const
Return the number of bits in the Vector type. Returns zero when the vector is a vector of pointers...
Type * getAllocatedType() const
ID
LLVM Calling Convention Representation.
static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const DataLayout *TD)
Type * getPointerOperandType() const
uint64_t getZExtValue() const
Return the zero extended value.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
bool insert(const value_type &X)
Insert a new element into the SetVector.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
Get the constant's value with a saturation limit.
This class represents a no-op cast from one type to another.
bool empty() const
Determine if the SetVector is empty or not.
bool isFloatingPointTy() const
void replaceAllUsesWith(Value *V)
static Constant * getIntToPtr(Constant *C, Type *Ty)
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
This class represents a truncation of integer types.
Type * getElementType() const
unsigned getNumIncomingValues() const
uint64_t getElementOffset(unsigned Idx) const
uint64_t getElementOffsetInBits(unsigned Idx) const
unsigned getNumSuccessors() const
value_use_iterator< User > use_iterator
LLVM Basic Block Representation.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Type * getContainedType(unsigned i) const
Type * getElementType(unsigned N) const
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
LLVM Constant Representation.
PointerType * getType() const
bool onlyUsedByLifetimeMarkers(const Value *V)
bool isFloatTy() const
isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0)
unsigned getAlignment() const
Value * getRawDest() const
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=0)
BasicBlock * getIncomingBlock(unsigned i) const
uint64_t getNumElements() const
Value * getOperand(unsigned i) const
Integer representation type.
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
void setAlignment(unsigned Align)
static UndefValue * get(Type *T)
bool hasAllConstantIndices() const
LLVMContext & getContext() const
All values hold a context through their type.
MDNode * getVariable() const
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
static bool isSafePHIToSpeculate(PHINode *PN, const DataLayout *TD)
const Value * getTrueValue() const
void setMetadata(unsigned KindID, MDNode *Node)
static Constant * getSplat(unsigned NumElts, Constant *Elt)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
Get or create an IntegerType instance.
static Constant * getBitCast(Constant *C, Type *Ty)
static PointerType * getUnqual(Type *ElementType)
Class for constant integers.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Value * getIncomingValue(unsigned i) const
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
static MDNode * getIfExists(LLVMContext &Context, ArrayRef< Value * > Vals)
MDNode * getMetadata(unsigned KindID) const
void initializeSROA_SSAUpPass(PassRegistry &)
Type * getDestTy() const
Return the destination type, as a convenience.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
SequentialType * getType() const
Value * stripPointerCasts()
Strips off any unneeded pointer casts, all-zero GEPs and aliases from the specified value...
unsigned getElementContainingOffset(uint64_t Offset) const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
const BasicBlock & getEntryBlock() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Value * getArgOperand(unsigned i) const
Class for arbitrary precision integers.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * getOperand() const
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
INITIALIZE_PASS_BEGIN(SROA_DT,"scalarrepl","Scalar Replacement of Aggregates (DT)", false, false) INITIALIZE_PASS_END(SROA_DT
bool isDereferenceablePointer() const
uint64_t MinAlign(uint64_t A, uint64_t B)
static bool isSafeSelectToSpeculate(SelectInst *SI, const DataLayout *TD)
static IntegerType * getInt32Ty(LLVMContext &C)
unsigned getAlignment() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Scalar Replacement of false scalarrepl ssa
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=0)
Create and insert a memset to the specified pointer and the specified value.
const Type * getScalarType() const
unsigned getPrimitiveSizeInBits() const
static bool isCompatibleAggregate(Type *T1, Type *T2)
static bool HasPadding(Type *Ty, const DataLayout &TD)
static int const Threshold
Scalar Replacement of false
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
LLVM Value Representation.
void setAlignment(unsigned Align)
A vector that has set insertion semantics.
static VectorType * get(Type *ElementType, unsigned NumElements)
static bool isHomogeneousAggregate(Type *T, unsigned &NumElts, Type *&EltTy)
CallInst * CreateLifetimeStart(Value *Ptr, ConstantInt *Size=0)
Create a lifetime.start intrinsic.
void moveBefore(Instruction *MovePos)
uint64_t getTypeSizeInBits(Type *Ty) const
bool isPowerOf2_32(uint32_t Value)
const Value * getFalseValue() const
static GetElementPtrInst * CreateInBounds(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=0)
unsigned getNumElements() const
Random access to the elements.
const BasicBlock * getParent() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
CallInst * CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=0, MDNode *TBAAStructTag=0)
Create and insert a memcpy between the specified pointers.
gep_type_iterator gep_type_begin(const User *GEP)