| 399 | |
| 400 | namespace ftg { |
| 401 | static bool runCVP(Module &M) { |
| 402 | // Our custom lattice function and generic sparse propagation solver. |
| 403 | CVPLatticeFunc Lattice; |
| 404 | SparseSolver<CVPLatticeKey, CVPLatticeVal> Solver(&Lattice); |
| 405 | |
| 406 | // For each function in the module, if we can't track its arguments, let the |
| 407 | // generic solver assume it is executable. |
| 408 | for (Function &F : M) |
| 409 | if (!F.isDeclaration() && !canTrackArgumentsInterprocedurally(&F)) |
| 410 | Solver.MarkBlockExecutable(&F.front()); |
| 411 | |
| 412 | // Solver our custom lattice. In doing so, we will also build a set of |
| 413 | // indirect call sites. |
| 414 | Solver.Solve(); |
| 415 | |
| 416 | // Attach metadata to the indirect call sites that were collected indicating |
| 417 | // the set of functions they can possibly target. |
| 418 | // CustomCVP take the value of stripPointerCasts instead of pure CalledValue. |
| 419 | // According to evaluation result of CustomCVP, this value is more useful. |
| 420 | bool Changed = false; |
| 421 | MDBuilder MDB(M.getContext()); |
| 422 | for (Instruction *C : Lattice.getIndirectCalls()) { |
| 423 | auto *CB = dyn_cast_or_null<CallBase>(C); |
| 424 | if (!CB) |
| 425 | continue; |
| 426 | |
| 427 | auto *CO = CB->getCalledOperand(); |
| 428 | if (!CO) |
| 429 | continue; |
| 430 | |
| 431 | CO = CO->stripPointerCasts(); |
| 432 | if (!CO) |
| 433 | continue; |
| 434 | |
| 435 | auto RegI = CVPLatticeKey(CO, IPOGrouping::Register); |
| 436 | CVPLatticeVal LV = Solver.getExistingValueState(RegI); |
| 437 | if (!LV.isFunctionSet() || LV.getFunctions().empty()) |
| 438 | continue; |
| 439 | MDNode *Callees = MDB.createCallees(LV.getFunctions()); |
| 440 | C->setMetadata(LLVMContext::MD_callees, Callees); |
| 441 | Changed = true; |
| 442 | } |
| 443 | |
| 444 | return Changed; |
| 445 | } |
| 446 | |
| 447 | PreservedAnalyses CustomCVPPass::run(Module &M, ModuleAnalysisManager &) { |
| 448 | runCVP(M); |
no test coverage detected