bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) { // Constant folding for extract value is trivial. Constant *C = dyn_cast<Constant>(I.getAggregateOperand()); if (!C) C = SimplifiedValues.lookup(I.getAggregateOperand()); if (C) { SimplifiedValues[&I] = ConstantExpr::getExtractValue(C, I.getIndices()); return true; } // SROA can look through these but give them a cost. return false; }
/// substituteLPadValues - Substitute the values returned by the landingpad /// instruction with those returned by the personality function. void SjLjEHPrepare::substituteLPadValues(LandingPadInst *LPI, Value *ExnVal, Value *SelVal) { SmallVector<Value *, 8> UseWorkList(LPI->user_begin(), LPI->user_end()); while (!UseWorkList.empty()) { Value *Val = UseWorkList.pop_back_val(); ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Val); if (!EVI) continue; if (EVI->getNumIndices() != 1) continue; if (*EVI->idx_begin() == 0) EVI->replaceAllUsesWith(ExnVal); else if (*EVI->idx_begin() == 1) EVI->replaceAllUsesWith(SelVal); if (EVI->getNumUses() == 0) EVI->eraseFromParent(); } if (LPI->getNumUses() == 0) return; // There are still some uses of LPI. Construct an aggregate with the exception // values and replace the LPI with that aggregate. Type *LPadType = LPI->getType(); Value *LPadVal = UndefValue::get(LPadType); auto *SelI = cast<Instruction>(SelVal); IRBuilder<> Builder(SelI->getParent(), std::next(SelI->getIterator())); LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); LPI->replaceAllUsesWith(LPadVal); }
bool ExtractValueInstrumenter::CheckAndInstrument(Instruction* inst) { ExtractValueInst* evInst = dyn_cast<ExtractValueInst>(inst); if (evInst == NULL) { return false; } safe_assert(parent_ != NULL); count_++; InstrPtrVector instrs; Constant* iidC = IID_CONSTANT(evInst); Constant* inxC = computeIndex(evInst); Value* aggOp = evInst->getAggregateOperand(); Constant* aggOpInxC = computeIndex(aggOp); KVALUE_STRUCTVALUE(aggOp, instrs); for (ExtractValueInst::idx_iterator idx = evInst->idx_begin(); idx != evInst->idx_end(); idx++) { Constant* idxOp = INT32_CONSTANT(*idx, UNSIGNED); Instruction* call = CALL_INT("llvm_push_getelementptr_inx2", idxOp); instrs.push_back(call); } Instruction* call = CALL_IID_INT_INT("llvm_extractvalue", iidC, inxC, aggOpInxC); instrs.push_back(call); InsertAllBefore(instrs, evInst); return true; }
void GraphBuilder::visitExtractValueInst(ExtractValueInst& I) { DSNodeHandle Ptr = getValueDest(I.getOperand(0)); // Make that the node is read from... Ptr.getNode()->setReadMarker(); unsigned Offset = 0; Type* STy = I.getAggregateOperand()->getType(); llvm::ExtractValueInst::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 typerecord exists... Ptr.getNode()->mergeTypeInfo(I.getType(), Offset); if (isa<PointerType>(I.getType())) setDestTo(I, getLink(Ptr)); }
// -- handle ExtractValue instruction -- void UnsafeTypeCastingCheck::handleExtractValueInstruction(Instruction *inst) { ExtractValueInst *einst = dyn_cast<ExtractValueInst>(inst); if (einst == NULL) utccAbort("handleExtractValueInstruction cannot process with a non-extractvalue instruction"); setExprType(einst, llvmT2utccT(einst->getType())); }
bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) { AtomicOrdering SuccessOrder = CI->getSuccessOrdering(); AtomicOrdering FailureOrder = CI->getFailureOrdering(); Value *Addr = CI->getPointerOperand(); BasicBlock *BB = CI->getParent(); Function *F = BB->getParent(); LLVMContext &Ctx = F->getContext(); // If getInsertFencesForAtomic() returns true, then the target does not want // to deal with memory orders, and emitLeading/TrailingFence should take care // of everything. Otherwise, emitLeading/TrailingFence are no-op and we // should preserve the ordering. AtomicOrdering MemOpOrder = TLI->getInsertFencesForAtomic() ? Monotonic : SuccessOrder; // Given: cmpxchg some_op iN* %addr, iN %desired, iN %new success_ord fail_ord // // The full expansion we produce is: // [...] // fence? // cmpxchg.start: // %loaded = @load.linked(%addr) // %should_store = icmp eq %loaded, %desired // br i1 %should_store, label %cmpxchg.trystore, // label %cmpxchg.nostore // cmpxchg.trystore: // %stored = @store_conditional(%new, %addr) // %success = icmp eq i32 %stored, 0 // br i1 %success, label %cmpxchg.success, label %loop/%cmpxchg.failure // cmpxchg.success: // fence? // br label %cmpxchg.end // cmpxchg.nostore: // @load_linked_fail_balance()? // br label %cmpxchg.failure // cmpxchg.failure: // fence? // br label %cmpxchg.end // cmpxchg.end: // %success = phi i1 [true, %cmpxchg.success], [false, %cmpxchg.failure] // %restmp = insertvalue { iN, i1 } undef, iN %loaded, 0 // %res = insertvalue { iN, i1 } %restmp, i1 %success, 1 // [...] BasicBlock *ExitBB = BB->splitBasicBlock(CI->getIterator(), "cmpxchg.end"); auto FailureBB = BasicBlock::Create(Ctx, "cmpxchg.failure", F, ExitBB); auto NoStoreBB = BasicBlock::Create(Ctx, "cmpxchg.nostore", F, FailureBB); auto SuccessBB = BasicBlock::Create(Ctx, "cmpxchg.success", F, NoStoreBB); auto TryStoreBB = BasicBlock::Create(Ctx, "cmpxchg.trystore", F, SuccessBB); auto LoopBB = BasicBlock::Create(Ctx, "cmpxchg.start", F, TryStoreBB); // This grabs the DebugLoc from CI IRBuilder<> Builder(CI); // The split call above "helpfully" added a branch at the end of BB (to the // wrong place), but we might want a fence too. It's easiest to just remove // the branch entirely. std::prev(BB->end())->eraseFromParent(); Builder.SetInsertPoint(BB); TLI->emitLeadingFence(Builder, SuccessOrder, /*IsStore=*/true, /*IsLoad=*/true); Builder.CreateBr(LoopBB); // Start the main loop block now that we've taken care of the preliminaries. Builder.SetInsertPoint(LoopBB); Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder); Value *ShouldStore = Builder.CreateICmpEQ(Loaded, CI->getCompareOperand(), "should_store"); // If the cmpxchg doesn't actually need any ordering when it fails, we can // jump straight past that fence instruction (if it exists). Builder.CreateCondBr(ShouldStore, TryStoreBB, NoStoreBB); Builder.SetInsertPoint(TryStoreBB); Value *StoreSuccess = TLI->emitStoreConditional( Builder, CI->getNewValOperand(), Addr, MemOpOrder); StoreSuccess = Builder.CreateICmpEQ( StoreSuccess, ConstantInt::get(Type::getInt32Ty(Ctx), 0), "success"); Builder.CreateCondBr(StoreSuccess, SuccessBB, CI->isWeak() ? FailureBB : LoopBB); // Make sure later instructions don't get reordered with a fence if necessary. Builder.SetInsertPoint(SuccessBB); TLI->emitTrailingFence(Builder, SuccessOrder, /*IsStore=*/true, /*IsLoad=*/true); Builder.CreateBr(ExitBB); Builder.SetInsertPoint(NoStoreBB); // In the failing case, where we don't execute the store-conditional, the // target might want to balance out the load-linked with a dedicated // instruction (e.g., on ARM, clearing the exclusive monitor). TLI->emitAtomicCmpXchgNoStoreLLBalance(Builder); Builder.CreateBr(FailureBB); Builder.SetInsertPoint(FailureBB); TLI->emitTrailingFence(Builder, FailureOrder, /*IsStore=*/true, /*IsLoad=*/true); Builder.CreateBr(ExitBB); // Finally, we have control-flow based knowledge of whether the cmpxchg // succeeded or not. We expose this to later passes by converting any // subsequent "icmp eq/ne %loaded, %oldval" into a use of an appropriate PHI. // Setup the builder so we can create any PHIs we need. Builder.SetInsertPoint(ExitBB, ExitBB->begin()); PHINode *Success = Builder.CreatePHI(Type::getInt1Ty(Ctx), 2); Success->addIncoming(ConstantInt::getTrue(Ctx), SuccessBB); Success->addIncoming(ConstantInt::getFalse(Ctx), FailureBB); // Look for any users of the cmpxchg that are just comparing the loaded value // against the desired one, and replace them with the CFG-derived version. SmallVector<ExtractValueInst *, 2> PrunedInsts; for (auto User : CI->users()) { ExtractValueInst *EV = dyn_cast<ExtractValueInst>(User); if (!EV) continue; assert(EV->getNumIndices() == 1 && EV->getIndices()[0] <= 1 && "weird extraction from { iN, i1 }"); if (EV->getIndices()[0] == 0) EV->replaceAllUsesWith(Loaded); else EV->replaceAllUsesWith(Success); PrunedInsts.push_back(EV); } // We can remove the instructions now we're no longer iterating through them. for (auto EV : PrunedInsts) EV->eraseFromParent(); if (!CI->use_empty()) { // Some use of the full struct return that we don't understand has happened, // so we've got to reconstruct it properly. Value *Res; Res = Builder.CreateInsertValue(UndefValue::get(CI->getType()), Loaded, 0); Res = Builder.CreateInsertValue(Res, Success, 1); CI->replaceAllUsesWith(Res); } CI->eraseFromParent(); return true; }
// SurveyFunction - This performs the initial survey of the specified function, // checking out whether or not it uses any of its incoming arguments or whether // any callers use the return value. This fills in the LiveValues set and Uses // map. // // We consider arguments of non-internal functions to be intrinsically alive as // well as arguments to functions which have their "address taken". // void DAE::SurveyFunction(Function &F) { unsigned RetCount = NumRetVals(&F); // Assume all return values are dead typedef SmallVector<Liveness, 5> RetVals; RetVals RetValLiveness(RetCount, MaybeLive); typedef SmallVector<UseVector, 5> RetUses; // These vectors map each return value to the uses that make it MaybeLive, so // we can add those to the Uses map if the return value really turns out to be // MaybeLive. Initialized to a list of RetCount empty lists. RetUses MaybeLiveRetUses(RetCount); for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) if (RI->getNumOperands() != 0 && RI->getOperand(0)->getType() != F.getFunctionType()->getReturnType()) { // We don't support old style multiple return values. MarkLive(F); return; } if (!F.hasLocalLinkage() && (!ShouldHackArguments() || F.isIntrinsic())) { MarkLive(F); return; } DEBUG(dbgs() << "DAE - Inspecting callers for fn: " << F.getName() << "\n"); // Keep track of the number of live retvals, so we can skip checks once all // of them turn out to be live. unsigned NumLiveRetVals = 0; const Type *STy = dyn_cast<StructType>(F.getReturnType()); // Loop all uses of the function. for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) { // If the function is PASSED IN as an argument, its address has been // taken. CallSite CS = CallSite::get(*I); if (!CS.getInstruction() || !CS.isCallee(I)) { MarkLive(F); return; } // If this use is anything other than a call site, the function is alive. Instruction *TheCall = CS.getInstruction(); if (!TheCall) { // Not a direct call site? MarkLive(F); return; } // If we end up here, we are looking at a direct call to our function. // Now, check how our return value(s) is/are used in this caller. Don't // bother checking return values if all of them are live already. if (NumLiveRetVals != RetCount) { if (STy) { // Check all uses of the return value. for (Value::use_iterator I = TheCall->use_begin(), E = TheCall->use_end(); I != E; ++I) { ExtractValueInst *Ext = dyn_cast<ExtractValueInst>(*I); if (Ext && Ext->hasIndices()) { // This use uses a part of our return value, survey the uses of // that part and store the results for this index only. unsigned Idx = *Ext->idx_begin(); if (RetValLiveness[Idx] != Live) { RetValLiveness[Idx] = SurveyUses(Ext, MaybeLiveRetUses[Idx]); if (RetValLiveness[Idx] == Live) NumLiveRetVals++; } } else { // Used by something else than extractvalue. Mark all return // values as live. for (unsigned i = 0; i != RetCount; ++i ) RetValLiveness[i] = Live; NumLiveRetVals = RetCount; break; } } } else { // Single return value RetValLiveness[0] = SurveyUses(TheCall, MaybeLiveRetUses[0]); if (RetValLiveness[0] == Live) NumLiveRetVals = RetCount; } } } // Now we've inspected all callers, record the liveness of our return values. for (unsigned i = 0; i != RetCount; ++i) MarkValue(CreateRet(&F, i), RetValLiveness[i], MaybeLiveRetUses[i]); DEBUG(dbgs() << "DAE - Inspecting args for fn: " << F.getName() << "\n"); // Now, check all of our arguments. unsigned i = 0; UseVector MaybeLiveArgUses; for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); AI != E; ++AI, ++i) { // See what the effect of this use is (recording any uses that cause // MaybeLive in MaybeLiveArgUses). Liveness Result = SurveyUses(AI, MaybeLiveArgUses); // Mark the result. MarkValue(CreateArg(&F, i), Result, MaybeLiveArgUses); // Clear the vector again for the next iteration. MaybeLiveArgUses.clear(); } }
// // 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 SimplifyEV::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;) { ExtractValueInst *EV = dyn_cast<ExtractValueInst>(I++); if(!EV) continue; Value *Agg = EV->getAggregateOperand(); if (!EV->hasIndices()) { EV->replaceAllUsesWith(Agg); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } if (Constant *C = dyn_cast<Constant>(Agg)) { if (isa<UndefValue>(C)) { EV->replaceAllUsesWith(UndefValue::get(EV->getType())); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } if (isa<ConstantAggregateZero>(C)) { EV->replaceAllUsesWith(Constant::getNullValue(EV->getType())); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } if (isa<ConstantArray>(C) || isa<ConstantStruct>(C)) { // Extract the element indexed by the first index out of the constant Value *V = C->getOperand(*EV->idx_begin()); if (EV->getNumIndices() > 1) { // Extract the remaining indices out of the constant indexed by the // first index ExtractValueInst *EV_new = ExtractValueInst::Create(V, EV->getIndices().slice(1), "", EV); EV->replaceAllUsesWith(EV_new); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } else { EV->replaceAllUsesWith(V); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } } continue; } if (LoadInst * LI = dyn_cast<LoadInst>(Agg)) { // if the Agg value came from a load instruction // replace the extract value intruction with // a gep and a load. SmallVector<Value*, 8> Indices; Type *Int32Ty = Type::getInt32Ty(M.getContext()); Indices.push_back(Constant::getNullValue(Int32Ty)); for (ExtractValueInst::idx_iterator I = EV->idx_begin(), E = EV->idx_end(); I != E; ++I) { Indices.push_back(ConstantInt::get(Int32Ty, *I)); } GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(LI->getOperand(0), Indices, LI->getName(), LI) ; LoadInst *LINew = new LoadInst(GEP, "", LI); EV->replaceAllUsesWith(LINew); EV->eraseFromParent(); changed = true; numErased++; continue; } if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) { bool done = false; // We're extracting from an insertvalue instruction, compare the indices const unsigned *exti, *exte, *insi, *inse; for (exti = EV->idx_begin(), insi = IV->idx_begin(), exte = EV->idx_end(), inse = IV->idx_end(); exti != exte && insi != inse; ++exti, ++insi) { if (*insi != *exti) { // The insert and extract both reference distinctly different elements. // This means the extract is not influenced by the insert, and we can // replace the aggregate operand of the extract with the aggregate // operand of the insert. i.e., replace // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1 // %E = extractvalue { i32, { i32 } } %I, 0 // with // %E = extractvalue { i32, { i32 } } %A, 0 ExtractValueInst *EV_new = ExtractValueInst::Create(IV->getAggregateOperand(), EV->getIndices(), "", EV); EV->replaceAllUsesWith(EV_new); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; done = true; changed = true; break; } } if(done) continue; if (exti == exte && insi == inse) { // Both iterators are at the end: Index lists are identical. Replace // %B = insertvalue { i32, { i32 } } %A, i32 42, 1, 0 // %C = extractvalue { i32, { i32 } } %B, 1, 0 // with "i32 42" EV->replaceAllUsesWith(IV->getInsertedValueOperand()); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } if (exti == exte) { // The extract list is a prefix of the insert list. i.e. replace // %I = insertvalue { i32, { i32 } } %A, i32 42, 1, 0 // %E = extractvalue { i32, { i32 } } %I, 1 // with // %X = extractvalue { i32, { i32 } } %A, 1 // %E = insertvalue { i32 } %X, i32 42, 0 // by switching the order of the insert and extract (though the // insertvalue should be left in, since it may have other uses). Value *NewEV = ExtractValueInst::Create(IV->getAggregateOperand(), EV->getIndices(), "", EV); Value *NewIV = InsertValueInst::Create(NewEV, IV->getInsertedValueOperand(), makeArrayRef(insi, inse), "", EV); EV->replaceAllUsesWith(NewIV); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } if (insi == inse) { // The insert list is a prefix of the extract list // We can simply remove the common indices from the extract and make it // operate on the inserted value instead of the insertvalue result. // i.e., replace // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1 // %E = extractvalue { i32, { i32 } } %I, 1, 0 // with // %E extractvalue { i32 } { i32 42 }, 0 ExtractValueInst *EV_new = ExtractValueInst::Create(IV->getInsertedValueOperand(), makeArrayRef(exti, exte), "", EV); EV->replaceAllUsesWith(EV_new); DEBUG(errs() << "EV:"); DEBUG(errs() << "ERASE:"); DEBUG(EV->dump()); EV->eraseFromParent(); numErased++; changed = true; continue; } } } } } } while(changed); return (numErased > 0); }