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())); }
// // 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); }
/// GetExceptionObject - Return the exception object from the value passed into /// the 'resume' instruction (typically an aggregate). Clean up any dead /// instructions, including the 'resume' instruction. Value *DwarfEHPrepare::GetExceptionObject(ResumeInst *RI) { Value *V = RI->getOperand(0); Value *ExnObj = 0; InsertValueInst *SelIVI = dyn_cast<InsertValueInst>(V); LoadInst *SelLoad = 0; InsertValueInst *ExcIVI = 0; bool EraseIVIs = false; if (SelIVI) { if (SelIVI->getNumIndices() == 1 && *SelIVI->idx_begin() == 1) { ExcIVI = dyn_cast<InsertValueInst>(SelIVI->getOperand(0)); if (ExcIVI && isa<UndefValue>(ExcIVI->getOperand(0)) && ExcIVI->getNumIndices() == 1 && *ExcIVI->idx_begin() == 0) { ExnObj = ExcIVI->getOperand(1); SelLoad = dyn_cast<LoadInst>(SelIVI->getOperand(1)); EraseIVIs = true; } } } if (!ExnObj) ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI); RI->eraseFromParent(); if (EraseIVIs) { if (SelIVI->getNumUses() == 0) SelIVI->eraseFromParent(); if (ExcIVI->getNumUses() == 0) ExcIVI->eraseFromParent(); if (SelLoad && SelLoad->getNumUses() == 0) SelLoad->eraseFromParent(); } return ExnObj; }