Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 084a1d9

Browse files
authored
More array splitting, handle select and phi (#179)
* split up select and phi operations on arrays, to parallel what we do for structs, in the legalization * fix places where it said struct but should say array
1 parent 43fb415 commit 084a1d9

File tree

1 file changed

+88
-7
lines changed

1 file changed

+88
-7
lines changed

lib/Target/JSBackend/NaCl/ExpandStructRegs.cpp

+88-7
Original file line numberDiff line numberDiff line change
@@ -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

288288
static 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+
322397
static 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

Comments
 (0)