@@ -1541,45 +1541,79 @@ State LateLowerGCFrame::LocalScan(Function &F) {
1541
1541
assert (cast<PointerType>(CI->getArgOperand (0 )->getType ())->isOpaqueOrPointeeTypeMatches (getAttributeAtIndex (CI->getAttributes (), 1 , Attribute::StructRet).getValueAsType ()));
1542
1542
auto tracked = CountTrackedPointers (ElT, true );
1543
1543
if (tracked.count ) {
1544
- AllocaInst *SRet = dyn_cast<AllocaInst>((CI->arg_begin ()[0 ])->stripInBoundsOffsets ());
1545
- assert (SRet);
1546
- {
1544
+ SmallVector<AllocaInst *> allocas;
1545
+ Value *SRetArg = (CI->arg_begin ()[0 ])->stripInBoundsOffsets ();
1546
+ if (AllocaInst *OneSRet = dyn_cast<AllocaInst>(SRetArg)) {
1547
+ allocas.push_back (OneSRet);
1548
+ } else {
1549
+ SmallVector<Value *> worklist;
1550
+ worklist.push_back (SRetArg);
1551
+ while (!worklist.empty ()) {
1552
+ Value *V = worklist.pop_back_val ();
1553
+ if (AllocaInst *Alloca = dyn_cast<AllocaInst>(V->stripInBoundsOffsets ())) {
1554
+ allocas.push_back (Alloca);
1555
+ } else if (PHINode *Phi = dyn_cast<PHINode>(V)) {
1556
+ for (Value *Incoming : Phi->incoming_values ()) {
1557
+ worklist.push_back (Incoming);
1558
+ }
1559
+ } else if (SelectInst *SI = dyn_cast<SelectInst>(SRetArg)) {
1560
+ AllocaInst *TrueSRet = dyn_cast<AllocaInst>(SI->getTrueValue ());
1561
+ AllocaInst *FalseSRet = dyn_cast<AllocaInst>(SI->getFalseValue ());
1562
+ if (TrueSRet && FalseSRet) {
1563
+ worklist.push_back (TrueSRet);
1564
+ worklist.push_back (FalseSRet);
1565
+ } else {
1566
+ llvm_dump (SI);
1567
+ assert (false && " Malformed Select" );
1568
+ }
1569
+ } else {
1570
+ llvm_dump (V);
1571
+ assert (false && " Unexpected SRet argument" );
1572
+ }
1573
+ }
1574
+ }
1575
+ assert (allocas.size () > 0 );
1576
+ assert (std::all_of (allocas.begin (), allocas.end (), [&] (AllocaInst* SRetAlloca) {return (SRetAlloca->getArraySize () == allocas[0 ]->getArraySize () && SRetAlloca->getAllocatedType () == allocas[0 ]->getAllocatedType ());}));
1577
+ for (AllocaInst *SRet : allocas) {
1547
1578
if (!(SRet->isStaticAlloca () && isa<PointerType>(ElT) && ElT->getPointerAddressSpace () == AddressSpace::Tracked)) {
1548
1579
assert (!tracked.derived );
1549
1580
if (tracked.all ) {
1550
1581
S.ArrayAllocas [SRet] = tracked.count * cast<ConstantInt>(SRet->getArraySize ())->getZExtValue ();
1551
1582
}
1552
1583
else {
1553
1584
Value *arg1 = (CI->arg_begin ()[1 ])->stripInBoundsOffsets ();
1554
- AllocaInst *SRet_gc = nullptr ;
1555
- if (PHINode *Phi = dyn_cast<PHINode>(arg1)) {
1556
- for (Value *V : Phi->incoming_values ()) {
1557
- if (AllocaInst *Alloca = dyn_cast<AllocaInst>(V->stripInBoundsOffsets ())) {
1558
- if (SRet_gc == nullptr ) {
1559
- SRet_gc = Alloca;
1560
- } else if (SRet_gc == Alloca) {
1561
- continue ;
1562
- } else {
1563
- llvm_dump (Alloca);
1564
- llvm_dump (SRet_gc);
1565
- assert (false && " Allocas in Phi node should match" );
1566
- }
1585
+ SmallVector<AllocaInst *> gc_allocas;
1586
+ SmallVector<Value*> worklist;
1587
+ worklist.push_back (arg1);
1588
+ while (!worklist.empty ()) {
1589
+ Value *V = worklist.pop_back_val ();
1590
+ if (AllocaInst *Alloca = dyn_cast<AllocaInst>(V->stripInBoundsOffsets ())) {
1591
+ gc_allocas.push_back (Alloca);
1592
+ } else if (PHINode *Phi = dyn_cast<PHINode>(V)) {
1593
+ for (Value *Incoming : Phi->incoming_values ()) {
1594
+ worklist.push_back (Incoming);
1595
+ }
1596
+ } else if (SelectInst *SI = dyn_cast<SelectInst>(arg1)) {
1597
+ AllocaInst *TrueSRet = dyn_cast<AllocaInst>(SI->getTrueValue ());
1598
+ AllocaInst *FalseSRet = dyn_cast<AllocaInst>(SI->getFalseValue ());
1599
+ if (TrueSRet && FalseSRet) {
1600
+ worklist.push_back (TrueSRet);
1601
+ worklist.push_back (FalseSRet);
1567
1602
} else {
1568
- llvm_dump (V-> stripInBoundsOffsets () );
1569
- assert (false && " Expected alloca " );
1603
+ llvm_dump (SI );
1604
+ assert (false && " Malformed Select " );
1570
1605
}
1606
+ } else {
1607
+ llvm_dump (V);
1608
+ assert (false && " Unexpected SRet argument" );
1571
1609
}
1572
- } else {
1573
- SRet_gc = dyn_cast<AllocaInst>(arg1);
1574
1610
}
1575
- if (!SRet_gc) {
1576
- llvm_dump (CI);
1577
- llvm_dump (arg1);
1578
- assert (false && " Expected alloca" );
1579
- }
1580
- Type *ElT = SRet_gc->getAllocatedType ();
1581
- if (!(SRet_gc->isStaticAlloca () && isa<PointerType>(ElT) && ElT->getPointerAddressSpace () == AddressSpace::Tracked)) {
1582
- S.ArrayAllocas [SRet_gc] = tracked.count * cast<ConstantInt>(SRet_gc->getArraySize ())->getZExtValue ();
1611
+
1612
+ assert (gc_allocas.size () > 0 );
1613
+ assert (std::all_of (gc_allocas.begin (), gc_allocas.end (), [&] (AllocaInst* SRetAlloca) {return (SRetAlloca->getArraySize () == gc_allocas[0 ]->getArraySize () && SRetAlloca->getAllocatedType () == gc_allocas[0 ]->getAllocatedType ());}));
1614
+ for (AllocaInst *SRet_gc : gc_allocas) {
1615
+ if (!(SRet_gc->isStaticAlloca () && isa<PointerType>(ElT) && ElT->getPointerAddressSpace () == AddressSpace::Tracked))
1616
+ S.ArrayAllocas [SRet_gc] = tracked.count * cast<ConstantInt>(SRet_gc->getArraySize ())->getZExtValue ();
1583
1617
}
1584
1618
}
1585
1619
}
0 commit comments