@@ -93,46 +93,74 @@ bool StructInitVec::runOnRegion(Region &Rgn, const Analyses &A) {
9393 Operands.push_back (Op);
9494 }
9595 BasicBlock *BB = Bndl[0 ]->getParent ();
96- // TODO: For now we only support load operands.
97- // TODO: For now we don't cross BBs.
98- if (!all_of (Operands, [BB](Value *V) {
99- auto *LI = dyn_cast<LoadInst>(V);
100- if (LI == nullptr )
101- return false ;
102- if (LI->getParent () != BB)
103- return false ;
104- if (LI->hasNUsesOrMore (2 ))
105- return false ;
106- return true ;
107- }))
108- return false ;
109- // TODO: Try to avoid the extra copy to an instruction vector.
110- SmallVector<Instruction *, 8 > Loads;
111- Loads.reserve (Operands.size ());
112- for (Value *Op : Operands)
113- Loads.push_back (cast<Instruction>(Op));
114-
115- bool Consecutive = VecUtils::areConsecutive<LoadInst, Instruction>(
116- Loads, A.getScalarEvolution (), *DL);
117- if (!Consecutive)
118- return false ;
119- if (!canVectorize (Loads, Sched))
96+ bool AllLoads = all_of (Operands, [BB](Value *V) {
97+ auto *LI = dyn_cast<LoadInst>(V);
98+ if (LI == nullptr )
99+ return false ;
100+ // TODO: For now we don't cross BBs.
101+ if (LI->getParent () != BB)
102+ return false ;
103+ if (LI->hasNUsesOrMore (2 ))
104+ return false ;
105+ return true ;
106+ });
107+ bool AllConstants =
108+ all_of (Operands, [](Value *V) { return isa<Constant>(V); });
109+ if (!AllLoads && !AllConstants)
120110 return false ;
121111
122- // Generate vector store and vector load
123- Type *Ty = VecUtils::getCombinedVectorTypeFor (Bndl, *DL);
124- Value *LdPtr = cast<LoadInst>(Loads[0 ])->getPointerOperand ();
125- // TODO: Compute alignment.
126- Align LdAlign (1 );
127- auto LdWhereIt = std::next (VecUtils::getLowest (Loads)->getIterator ());
128- auto *VecLd =
129- LoadInst::create (Ty, LdPtr, LdAlign, LdWhereIt, Ctx, " VecIinitL" );
112+ Value *VecOp = nullptr ;
113+ SmallVector<Instruction *, 8 > Loads;
114+ if (AllLoads) {
115+ // TODO: Try to avoid the extra copy to an instruction vector.
116+ Loads.reserve (Operands.size ());
117+ for (Value *Op : Operands)
118+ Loads.push_back (cast<Instruction>(Op));
119+
120+ bool Consecutive = VecUtils::areConsecutive<LoadInst, Instruction>(
121+ Loads, A.getScalarEvolution (), *DL);
122+ if (!Consecutive)
123+ return false ;
124+ if (!canVectorize (Loads, Sched))
125+ return false ;
126+
127+ // Generate vector load.
128+ Type *Ty = VecUtils::getCombinedVectorTypeFor (Bndl, *DL);
129+ Value *LdPtr = cast<LoadInst>(Loads[0 ])->getPointerOperand ();
130+ // TODO: Compute alignment.
131+ Align LdAlign (1 );
132+ auto LdWhereIt = std::next (VecUtils::getLowest (Loads)->getIterator ());
133+ VecOp = LoadInst::create (Ty, LdPtr, LdAlign, LdWhereIt, Ctx, " VecIinitL" );
134+ } else if (AllConstants) {
135+ SmallVector<Constant *, 8 > Constants;
136+ Constants.reserve (Operands.size ());
137+ for (Value *Op : Operands) {
138+ auto *COp = cast<Constant>(Op);
139+ if (auto *AggrCOp = dyn_cast<ConstantAggregate>(COp)) {
140+ // If the operand is a constant aggregate, then append all its elements.
141+ for (Value *Elm : AggrCOp->operands ())
142+ Constants.push_back (cast<Constant>(Elm));
143+ } else if (auto *SeqCOp = dyn_cast<ConstantDataSequential>(COp)) {
144+ for (auto ElmIdx : seq<unsigned >(SeqCOp->getNumElements ()))
145+ Constants.push_back (SeqCOp->getElementAsConstant (ElmIdx));
146+ } else if (auto *Zero = dyn_cast<ConstantAggregateZero>(COp)) {
147+ auto *ZeroElm = Zero->getSequentialElement ();
148+ for (auto ElmIdx :
149+ seq<unsigned >(Zero->getElementCount ().getFixedValue ()))
150+ Constants.push_back (ZeroElm);
151+ } else {
152+ Constants.push_back (COp);
153+ }
154+ }
155+ VecOp = ConstantVector::get (Constants);
156+ }
130157
158+ // Generate vector store.
131159 Value *StPtr = cast<StoreInst>(Bndl[0 ])->getPointerOperand ();
132160 // TODO: Compute alignment.
133161 Align StAlign (1 );
134162 auto StWhereIt = std::next (VecUtils::getLowest (Bndl)->getIterator ());
135- StoreInst::create (VecLd , StPtr, StAlign, StWhereIt, Ctx);
163+ StoreInst::create (VecOp , StPtr, StAlign, StWhereIt, Ctx);
136164
137165 tryEraseDeadInstrs (Bndl, Loads);
138166 return true ;
0 commit comments