void GraphBuilder::visitInsertValueInst(InsertValueInst& I) { setDestTo(I, createNode()->setAllocaMarker()); Type *StoredTy = I.getInsertedValueOperand()->getType(); DSNodeHandle Dest = getValueDest(&I); Dest.mergeWith(getValueDest(I.getAggregateOperand())); // Mark that the node is written to... Dest.getNode()->setModifiedMarker(); unsigned Offset = 0; Type* STy = I.getAggregateOperand()->getType(); llvm::InsertValueInst::idx_iterator i = I.idx_begin(), e = I.idx_end(); for (; i != e; i++) { const StructLayout *SL = TD.getStructLayout(cast<StructType>(STy)); Offset += SL->getElementOffset(*i); STy = (cast<StructType>(STy))->getTypeAtIndex(*i); } // Ensure a type-record exists... Dest.getNode()->mergeTypeInfo(StoredTy, Offset); // Avoid adding edges from null, or processing non-"pointer" stores if (isa<PointerType>(StoredTy)) Dest.addEdgeTo(getValueDest(I.getInsertedValueOperand())); }
bool CallAnalyzer::visitInsertValue(InsertValueInst &I) { // Constant folding for insert value is trivial. Constant *AggC = dyn_cast<Constant>(I.getAggregateOperand()); if (!AggC) AggC = SimplifiedValues.lookup(I.getAggregateOperand()); Constant *InsertedC = dyn_cast<Constant>(I.getInsertedValueOperand()); if (!InsertedC) InsertedC = SimplifiedValues.lookup(I.getInsertedValueOperand()); if (AggC && InsertedC) { SimplifiedValues[&I] = ConstantExpr::getInsertValue(AggC, InsertedC, I.getIndices()); return true; } // SROA can look through these but give them a cost. return false; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. Search for insertvalue instructions // that can be simplified. // // Inputs: // M - A reference to the LLVM module to transform. // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool SimplifyIV::runOnModule(Module& M) { // Repeat till no change bool changed; do { changed = false; std::vector<StoreInst*> worklist; for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { InsertValueInst *IV = dyn_cast<InsertValueInst>(I++); if(!IV) continue; // Find all insert value instructions. if(!IV->hasOneUse()) continue; // Check that its only use is a StoreInst StoreInst *SI = dyn_cast<StoreInst>(*(IV->use_begin())); if(!SI) continue; // Check that it is the stored value if(SI->getOperand(0) != IV) continue; changed = true; numErased++; do { // replace by a series of gep/stores SmallVector<Value*, 8> Indices; Type *Int32Ty = Type::getInt32Ty(M.getContext()); Indices.push_back(Constant::getNullValue(Int32Ty)); for (InsertValueInst::idx_iterator I = IV->idx_begin(), E = IV->idx_end(); I != E; ++I) { Indices.push_back(ConstantInt::get(Int32Ty, *I)); } GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(SI->getOperand(1), Indices, SI->getName(), SI) ; new StoreInst(IV->getInsertedValueOperand(), GEP, SI); IV = dyn_cast<InsertValueInst>(IV->getAggregateOperand()); } while(IV); worklist.push_back(SI); } } } while(!worklist.empty()) { StoreInst *SI = worklist.back(); worklist.pop_back(); SI->eraseFromParent(); } } while(changed); return (numErased > 0); }