brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · c0d0163 Raw
124 lines · cpp
1//===- ReduceMetadata.cpp - Specialized Delta Pass ------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements two functions used by the Generic Delta Debugging10// Algorithm, which are used to reduce Metadata nodes.11//12//===----------------------------------------------------------------------===//13 14#include "ReduceMetadata.h"15#include "llvm/ADT/Sequence.h"16#include "llvm/ADT/SmallVector.h"17#include "llvm/IR/InstIterator.h"18#include "llvm/IR/IntrinsicInst.h"19 20using namespace llvm;21 22extern cl::OptionCategory LLVMReduceOptions;23 24static cl::opt<bool> AggressiveMetadataReduction(25    "aggressive-named-md-reduction",26    cl::desc("Reduce named metadata without taking its type into account"),27    cl::cat(LLVMReduceOptions));28 29static bool shouldKeepDebugIntrinsicMetadata(Instruction &I, MDNode &MD) {30  return isa<DILocation>(MD) && isa<DbgInfoIntrinsic>(I);31}32 33static bool shouldKeepDebugNamedMetadata(NamedMDNode &MD) {34  return MD.getName() == "llvm.dbg.cu" && MD.getNumOperands() != 0;35}36 37// Named metadata with simple list-like behavior, so that it's valid to remove38// operands individually.39static constexpr StringLiteral ListNamedMetadata[] = {40  "llvm.module.flags",41  "llvm.ident",42  "opencl.spir.version",43  "opencl.ocl.version",44  "opencl.used.extensions",45  "opencl.used.optional.core.features",46  "opencl.compiler.options"47};48 49/// Remove unneeded arguments to named metadata.50void llvm::reduceNamedMetadataDeltaPass(Oracle &O, ReducerWorkItem &WorkItem) {51  Module &M = WorkItem.getModule();52 53  for (NamedMDNode &I : M.named_metadata()) {54    // If we don't want to reduce mindlessly, check if our node is part of55    // ListNamedMetadata before reducing it56    if (!AggressiveMetadataReduction &&57        !is_contained(ListNamedMetadata, I.getName()))58      continue;59 60    bool MadeChange = false;61    SmallVector<MDNode *> KeptOperands;62    for (auto J : seq<unsigned>(0, I.getNumOperands())) {63      if (O.shouldKeep())64        KeptOperands.push_back(I.getOperand(J));65      else66        MadeChange = true;67    }68 69    if (MadeChange) {70      I.clearOperands();71      for (MDNode *KeptOperand : KeptOperands)72        I.addOperand(KeptOperand);73    }74  }75}76 77/// Removes all the Named and Unnamed Metadata Nodes, as well as any debug78/// functions that aren't inside the desired Chunks.79void llvm::reduceMetadataDeltaPass(Oracle &O, ReducerWorkItem &WorkItem) {80  Module &Program = WorkItem.getModule();81 82  // Get out-of-chunk Named metadata nodes83  SmallVector<NamedMDNode *> NamedNodesToDelete;84  for (NamedMDNode &MD : Program.named_metadata())85    if (!shouldKeepDebugNamedMetadata(MD) && !O.shouldKeep())86      NamedNodesToDelete.push_back(&MD);87 88  for (NamedMDNode *NN : NamedNodesToDelete) {89    for (auto I : seq<unsigned>(0, NN->getNumOperands()))90      NN->setOperand(I, nullptr);91    NN->eraseFromParent();92  }93 94  // Delete out-of-chunk metadata attached to globals.95  for (GlobalVariable &GV : Program.globals()) {96    SmallVector<std::pair<unsigned, MDNode *>> MDs;97    GV.getAllMetadata(MDs);98    for (std::pair<unsigned, MDNode *> &MD : MDs)99      if (!O.shouldKeep())100        GV.setMetadata(MD.first, nullptr);101  }102 103  for (Function &F : Program) {104    {105      SmallVector<std::pair<unsigned, MDNode *>> MDs;106      // Delete out-of-chunk metadata attached to functions.107      F.getAllMetadata(MDs);108      for (std::pair<unsigned, MDNode *> &MD : MDs)109        if (!O.shouldKeep())110          F.setMetadata(MD.first, nullptr);111    }112 113    // Delete out-of-chunk metadata attached to instructions.114    for (Instruction &I : instructions(F)) {115      SmallVector<std::pair<unsigned, MDNode *>> MDs;116      I.getAllMetadata(MDs);117      for (std::pair<unsigned, MDNode *> &MD : MDs) {118        if (!shouldKeepDebugIntrinsicMetadata(I, *MD.second) && !O.shouldKeep())119          I.setMetadata(MD.first, nullptr);120      }121    }122  }123}124