diff options
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp index 078230e..7409a4a1 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceMetadata.cpp @@ -23,11 +23,18 @@ using namespace llvm; /// Removes all the Named and Unnamed Metadata Nodes, as well as any debug /// functions that aren't inside the desired Chunks. static void extractMetadataFromModule(Oracle &O, Module &Program) { + SmallSetVector<MDNode *, 8> NodesToVisit; + // Get out-of-chunk Named metadata nodes SmallVector<NamedMDNode *> NamedNodesToDelete; - for (NamedMDNode &MD : Program.named_metadata()) - if (!O.shouldKeep()) + for (NamedMDNode &MD : Program.named_metadata()) { + if (O.shouldKeep()) { + for (auto *Op : MD.operands()) + NodesToVisit.insert(Op); + } else { NamedNodesToDelete.push_back(&MD); + } + } for (NamedMDNode *NN : NamedNodesToDelete) { for (auto I : seq<unsigned>(0, NN->getNumOperands())) @@ -35,13 +42,30 @@ static void extractMetadataFromModule(Oracle &O, Module &Program) { NN->eraseFromParent(); } + // Delete elements from named metadata lists + for (auto &NamedList : Program.named_metadata()) { + SmallVector<MDNode *> NewOperands; + for (auto *Op : NamedList.operands()) + if (O.shouldKeep()) + NewOperands.push_back(Op); + if (NewOperands.size() == NamedList.getNumOperands()) + continue; + NamedList.clearOperands(); + for (auto *Op : NewOperands) + NamedList.addOperand(Op); + } + // Delete out-of-chunk metadata attached to globals. for (GlobalVariable &GV : Program.globals()) { SmallVector<std::pair<unsigned, MDNode *>> MDs; GV.getAllMetadata(MDs); - for (std::pair<unsigned, MDNode *> &MD : MDs) - if (!O.shouldKeep()) + for (std::pair<unsigned, MDNode *> &MD : MDs) { + if (O.shouldKeep()) { + NodesToVisit.insert(MD.second); + } else { GV.setMetadata(MD.first, nullptr); + } + } } for (Function &F : Program) { @@ -49,20 +73,57 @@ static void extractMetadataFromModule(Oracle &O, Module &Program) { SmallVector<std::pair<unsigned, MDNode *>> MDs; // Delete out-of-chunk metadata attached to functions. F.getAllMetadata(MDs); - for (std::pair<unsigned, MDNode *> &MD : MDs) - if (!O.shouldKeep()) + for (std::pair<unsigned, MDNode *> &MD : MDs) { + if (O.shouldKeep()) { + NodesToVisit.insert(MD.second); + } else { F.setMetadata(MD.first, nullptr); + } + } } // Delete out-of-chunk metadata attached to instructions. for (Instruction &I : instructions(F)) { SmallVector<std::pair<unsigned, MDNode *>> MDs; I.getAllMetadata(MDs); - for (std::pair<unsigned, MDNode *> &MD : MDs) - if (!O.shouldKeep()) + for (std::pair<unsigned, MDNode *> &MD : MDs) { + if (O.shouldKeep()) { + NodesToVisit.insert(MD.second); + } else { I.setMetadata(MD.first, nullptr); + } + } } } + + // Gather all metadata tuples and their parents + SmallVector<std::pair<MDNode *, unsigned>> OperandsOfTuples; + SmallSet<Metadata *, 8> VisitedNodes; + while (!NodesToVisit.empty()) { + auto *Node = NodesToVisit.pop_back_val(); + if (!VisitedNodes.insert(Node).second) + continue; + for (auto I : seq<unsigned>(0, Node->getNumOperands())) { + auto *Op = Node->getOperand(I).get(); + if (auto *MD = dyn_cast_or_null<MDNode>(Op)) + NodesToVisit.insert(MD); + if (isa_and_nonnull<MDTuple>(Op)) + OperandsOfTuples.push_back(std::make_pair(Node, I)); + } + } + + // Delete elements from metadata tuples + for (auto [Node, NodeOpID] : OperandsOfTuples) { + auto *Tuple = dyn_cast<MDTuple>(Node->getOperand(NodeOpID)); + SmallVector<Metadata *> NewOperands; + for (auto &Op : Tuple->operands()) + if (O.shouldKeep()) + NewOperands.push_back(Op.get()); + if (NewOperands.size() == Tuple->getNumOperands()) + continue; + Node->replaceOperandWith( + NodeOpID, MDTuple::get(Tuple->getContext(), makeArrayRef(NewOperands))); + } } void llvm::reduceMetadataDeltaPass(TestRunner &Test) { |