// 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); }