void GraphBuilder::visitLoadInst(LoadInst &LI) { // // Create a DSNode for the pointer dereferenced by the load. If the DSNode // is NULL, do nothing more (this can occur if the load is loading from a // NULL pointer constant (bugpoint can generate such code). // DSNodeHandle Ptr = getValueDest(LI.getPointerOperand()); if (Ptr.isNull()) return; // Load from null // Make that the node is read from... Ptr.getNode()->setReadMarker(); // Ensure a typerecord exists... Ptr.getNode()->growSizeForType(LI.getType(), Ptr.getOffset()); if (isa<PointerType>(LI.getType())) setDestTo(LI, getLink(Ptr)); // check that it is the inserted value if(TypeInferenceOptimize) if(LI.hasOneUse()) if(StoreInst *SI = dyn_cast<StoreInst>(*(LI.use_begin()))) if(SI->getOperand(0) == &LI) { ++NumIgnoredInst; return; } Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset()); }
/// MoveExtToFormExtLoad - Move a zext or sext fed by a load into the same /// basic block as the load, unless conditions are unfavorable. This allows /// SelectionDAG to fold the extend into the load. /// bool CodeGenPrepare::MoveExtToFormExtLoad(Instruction *I) { // Look for a load being extended. LoadInst *LI = dyn_cast<LoadInst>(I->getOperand(0)); if (!LI) return false; // If they're already in the same block, there's nothing to do. if (LI->getParent() == I->getParent()) return false; // If the load has other users and the truncate is not free, this probably // isn't worthwhile. if (!LI->hasOneUse() && TLI && (TLI->isTypeLegal(TLI->getValueType(LI->getType())) || !TLI->isTypeLegal(TLI->getValueType(I->getType()))) && !TLI->isTruncateFree(I->getType(), LI->getType())) return false; // Check whether the target supports casts folded into loads. unsigned LType; if (isa<ZExtInst>(I)) LType = ISD::ZEXTLOAD; else { assert(isa<SExtInst>(I) && "Unexpected ext type!"); LType = ISD::SEXTLOAD; } if (TLI && !TLI->isLoadExtLegal(LType, TLI->getValueType(LI->getType()))) return false; // Move the extend into the same block as the load, so that SelectionDAG // can fold it. I->removeFromParent(); I->insertAfter(LI); ++NumExtsMoved; return true; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. Search for insert/extractvalue 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 SimplifyLoad::runOnModule(Module& M) { // Repeat till no change bool changed; do { changed = false; 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;) { LoadInst *LI = dyn_cast<LoadInst>(I++); if(!LI) continue; if(LI->hasOneUse()) { if(CastInst *CI = dyn_cast<CastInst>(*(LI->use_begin()))) { if(LI->getType()->isPointerTy()) { if(ConstantExpr *CE = dyn_cast<ConstantExpr>(LI->getOperand(0))) { if(const PointerType *PTy = dyn_cast<PointerType>(CE->getOperand(0)->getType())) if(PTy->getElementType() == CI->getType()) { LoadInst *LINew = new LoadInst(CE->getOperand(0), "", LI); CI->replaceAllUsesWith(LINew); } } } } } } } } } while(changed); return (numErased > 0); }