@@ -259,7 +259,7 @@ static bool SplitUpArrayStore(StoreInst *Store, const DataLayout *DL) {
259259  ArrayType *ATy = cast<ArrayType>(Store->getValueOperand ()->getType ());
260260
261261  bool  NeedsAnotherPass = false ;
262-   //  Create a separate store instruction for each struct  field.
262+   //  Create a separate store instruction for each array  field.
263263  for  (unsigned  Index = 0 ; Index < ATy->getNumElements (); ++Index) {
264264    SmallVector<Value *, 2 > Indexes;
265265    Indexes.push_back (ConstantInt::get (Store->getContext (), APInt (32 , 0 )));
@@ -287,10 +287,10 @@ static bool SplitUpArrayStore(StoreInst *Store, const DataLayout *DL) {
287287
288288static  bool  SplitUpArrayLoad (LoadInst *Load, const  DataLayout *DL) {
289289  ArrayType *ATy = cast<ArrayType>(Load->getType ());
290-   Value *NewStruct  = UndefValue::get (ATy);
290+   Value *NewArray  = UndefValue::get (ATy);
291291
292292  bool  NeedsAnotherPass = false ;
293-   //  Create a separate load instruction for each struct  field.
293+   //  Create a separate load instruction for each array  field.
294294  for  (unsigned  Index = 0 ; Index < ATy->getNumElements (); ++Index) {
295295    SmallVector<Value *, 2 > Indexes;
296296    Indexes.push_back (ConstantInt::get (Load->getContext (), APInt (32 , 0 )));
@@ -305,20 +305,95 @@ static bool SplitUpArrayLoad(LoadInst *Load, const DataLayout *DL) {
305305    NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass (NewLoad);
306306    ProcessArrayLoadOrStoreAttrs (NewLoad, Load, ATy, Index, DL);
307307
308-     //  Reconstruct the struct  value.
308+     //  Reconstruct the array  value.
309309    SmallVector<unsigned , 1 > EVIndexes;
310310    EVIndexes.push_back (Index);
311-     NewStruct  =
312-         CopyDebug (InsertValueInst::Create (NewStruct , NewLoad, EVIndexes,
311+     NewArray  =
312+         CopyDebug (InsertValueInst::Create (NewArray , NewLoad, EVIndexes,
313313                                          Load->getName () + " .insert"  , Load),
314314                  Load);
315315  }
316-   Load->replaceAllUsesWith (NewStruct );
316+   Load->replaceAllUsesWith (NewArray );
317317  Load->eraseFromParent ();
318318
319319  return  NeedsAnotherPass;
320320}
321321
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+ 
322397static  bool  ExpandExtractValue (ExtractValueInst *EV,
323398                               SmallVectorImpl<Instruction *> *ToErase) {
324399  //  Search for the insertvalue instruction that inserts the struct field
@@ -543,11 +618,17 @@ bool ExpandStructRegs::runOnFunction(Function &Func) {
543618            if  (Phi->getType ()->isStructTy ()) {
544619              NeedsAnotherPass |= SplitUpPHINode (Phi);
545620              Changed = true ;
621+             }else  if  (Phi->getType ()->isArrayTy ()) {
622+               NeedsAnotherPass |= SplitUpArrayPHINode (Phi);
623+               Changed = true ;
546624            }
547625          } else  if  (SelectInst *Select = dyn_cast<SelectInst>(Inst)) {
548626            if  (Select->getType ()->isStructTy ()) {
549627              NeedsAnotherPass |= SplitUpSelect (Select);
550628              Changed = true ;
629+             } else  if  (Select->getType ()->isArrayTy ()) {
630+               NeedsAnotherPass |= SplitUpArraySelect (Select);
631+               Changed = true ;
551632            }
552633          }
553634        }
0 commit comments