@@ -259,7 +259,7 @@ static bool SplitUpArrayStore(StoreInst *Store, const DataLayout *DL) {
259
259
ArrayType *ATy = cast<ArrayType>(Store->getValueOperand ()->getType ());
260
260
261
261
bool NeedsAnotherPass = false ;
262
- // Create a separate store instruction for each struct field.
262
+ // Create a separate store instruction for each array field.
263
263
for (unsigned Index = 0 ; Index < ATy->getNumElements (); ++Index) {
264
264
SmallVector<Value *, 2 > Indexes;
265
265
Indexes.push_back (ConstantInt::get (Store->getContext (), APInt (32 , 0 )));
@@ -287,10 +287,10 @@ static bool SplitUpArrayStore(StoreInst *Store, const DataLayout *DL) {
287
287
288
288
static bool SplitUpArrayLoad (LoadInst *Load, const DataLayout *DL) {
289
289
ArrayType *ATy = cast<ArrayType>(Load->getType ());
290
- Value *NewStruct = UndefValue::get (ATy);
290
+ Value *NewArray = UndefValue::get (ATy);
291
291
292
292
bool NeedsAnotherPass = false ;
293
- // Create a separate load instruction for each struct field.
293
+ // Create a separate load instruction for each array field.
294
294
for (unsigned Index = 0 ; Index < ATy->getNumElements (); ++Index) {
295
295
SmallVector<Value *, 2 > Indexes;
296
296
Indexes.push_back (ConstantInt::get (Load->getContext (), APInt (32 , 0 )));
@@ -305,20 +305,95 @@ static bool SplitUpArrayLoad(LoadInst *Load, const DataLayout *DL) {
305
305
NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass (NewLoad);
306
306
ProcessArrayLoadOrStoreAttrs (NewLoad, Load, ATy, Index, DL);
307
307
308
- // Reconstruct the struct value.
308
+ // Reconstruct the array value.
309
309
SmallVector<unsigned , 1 > EVIndexes;
310
310
EVIndexes.push_back (Index);
311
- NewStruct =
312
- CopyDebug (InsertValueInst::Create (NewStruct , NewLoad, EVIndexes,
311
+ NewArray =
312
+ CopyDebug (InsertValueInst::Create (NewArray , NewLoad, EVIndexes,
313
313
Load->getName () + " .insert" , Load),
314
314
Load);
315
315
}
316
- Load->replaceAllUsesWith (NewStruct );
316
+ Load->replaceAllUsesWith (NewArray );
317
317
Load->eraseFromParent ();
318
318
319
319
return NeedsAnotherPass;
320
320
}
321
321
322
+ static bool SplitUpArraySelect (SelectInst *Select) {
323
+ ArrayType *ATy = cast<ArrayType>(Select->getType ());
324
+ Value *NewArray = UndefValue::get (ATy);
325
+
326
+ bool NeedsAnotherPass = false ;
327
+ // Create a separate select instruction for each array field.
328
+ for (unsigned Index = 0 ; Index < ATy->getNumElements (); ++Index) {
329
+ SmallVector<unsigned , 1 > EVIndexes;
330
+ EVIndexes.push_back (Index);
331
+ Value *TrueValue = ExtractValueInst::Create (Select->getTrueValue (),
332
+ EVIndexes, " " , Select);
333
+ Value *FalseValue = ExtractValueInst::Create (Select->getFalseValue (),
334
+ EVIndexes, " " , Select);
335
+ SelectInst *NewSelect = SelectInst::Create (Select->getCondition (),
336
+ TrueValue, FalseValue,
337
+ Select->getName (),
338
+ Select);
339
+ NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass (NewSelect);
340
+
341
+ // Reconstruct the struct value.
342
+ SmallVector<unsigned , 1 > IVIndexes;
343
+ IVIndexes.push_back (Index);
344
+ NewArray =
345
+ CopyDebug (InsertValueInst::Create (NewArray, NewSelect, IVIndexes,
346
+ Select->getName () + " .insert" , Select),
347
+ Select);
348
+ }
349
+ Select->replaceAllUsesWith (NewArray);
350
+ Select->eraseFromParent ();
351
+
352
+ return NeedsAnotherPass;
353
+ }
354
+
355
+ static bool SplitUpArrayPHINode (PHINode *Phi) {
356
+ ArrayType *ATy = cast<ArrayType>(Phi->getType ());
357
+
358
+ Value *NewArray = UndefValue::get (ATy);
359
+ Instruction *NewArrayInsertPt = &*Phi->getParent ()->getFirstInsertionPt ();
360
+
361
+ bool NeedsAnotherPass = false ;
362
+
363
+ // Create a separate PHINode for each array field.
364
+ for (unsigned Index = 0 ; Index < ATy->getNumElements (); ++Index) {
365
+ SmallVector<unsigned , 1 > EVIndexes;
366
+ EVIndexes.push_back (Index);
367
+
368
+ Type *ElemTy = ATy->getElementType ();
369
+ NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass (ElemTy);
370
+
371
+ PHINode *NewPhi = PHINode::Create (ElemTy, Phi->getNumIncomingValues (),
372
+ Phi->getName () + " .index" , Phi);
373
+ CopyDebug (NewPhi, Phi);
374
+ for (unsigned PhiIndex = 0 ; PhiIndex < Phi->getNumIncomingValues ();
375
+ ++PhiIndex) {
376
+ BasicBlock *IncomingBB = Phi->getIncomingBlock (PhiIndex);
377
+ Value *EV = CopyDebug (
378
+ ExtractValueInst::Create (Phi->getIncomingValue (PhiIndex), EVIndexes,
379
+ Phi->getName () + " .extract" ,
380
+ IncomingBB->getTerminator ()),
381
+ Phi);
382
+ NewPhi->addIncoming (EV, IncomingBB);
383
+ }
384
+
385
+ // Reconstruct the original array value.
386
+ NewArray = CopyDebug (InsertValueInst::Create (NewArray, NewPhi, EVIndexes,
387
+ Phi->getName () + " .insert" ,
388
+ NewArrayInsertPt),
389
+ Phi);
390
+ }
391
+ Phi->replaceAllUsesWith (NewArray);
392
+ Phi->eraseFromParent ();
393
+
394
+ return NeedsAnotherPass;
395
+ }
396
+
322
397
static bool ExpandExtractValue (ExtractValueInst *EV,
323
398
SmallVectorImpl<Instruction *> *ToErase) {
324
399
// Search for the insertvalue instruction that inserts the struct field
@@ -543,11 +618,17 @@ bool ExpandStructRegs::runOnFunction(Function &Func) {
543
618
if (Phi->getType ()->isStructTy ()) {
544
619
NeedsAnotherPass |= SplitUpPHINode (Phi);
545
620
Changed = true ;
621
+ }else if (Phi->getType ()->isArrayTy ()) {
622
+ NeedsAnotherPass |= SplitUpArrayPHINode (Phi);
623
+ Changed = true ;
546
624
}
547
625
} else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) {
548
626
if (Select->getType ()->isStructTy ()) {
549
627
NeedsAnotherPass |= SplitUpSelect (Select);
550
628
Changed = true ;
629
+ } else if (Select->getType ()->isArrayTy ()) {
630
+ NeedsAnotherPass |= SplitUpArraySelect (Select);
631
+ Changed = true ;
551
632
}
552
633
}
553
634
}
0 commit comments