ReduceMetadata.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements two functions used by the Generic Delta Debugging
  10. // Algorithm, which are used to reduce Metadata nodes.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "ReduceMetadata.h"
  14. #include "Delta.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. #include <vector>
  20. using namespace llvm;
  21. static bool shouldKeepDebugIntrinsicMetadata(Instruction &I, MDNode &MD) {
  22. return isa<DILocation>(MD) && isa<DbgInfoIntrinsic>(I);
  23. }
  24. static bool shouldKeepDebugNamedMetadata(NamedMDNode &MD) {
  25. return MD.getName() == "llvm.dbg.cu" && MD.getNumOperands() != 0;
  26. }
  27. // Named metadata with simple list-like behavior, so that it's valid to remove
  28. // operands individually.
  29. static constexpr StringLiteral ListNamedMetadata[] = {
  30. "llvm.module.flags",
  31. "llvm.ident",
  32. "opencl.spir.version",
  33. "opencl.ocl.version",
  34. "opencl.used.extensions",
  35. "opencl.used.optional.core.features",
  36. "opencl.compiler.options"
  37. };
  38. /// Remove unneeded arguments to named metadata.
  39. static void reduceNamedMetadataOperands(Oracle &O, ReducerWorkItem &WorkItem) {
  40. Module &M = WorkItem.getModule();
  41. for (StringRef MDName : ListNamedMetadata) {
  42. NamedMDNode *NamedNode = M.getNamedMetadata(MDName);
  43. if (!NamedNode)
  44. continue;
  45. bool MadeChange = false;
  46. SmallVector<MDNode *, 16> KeptOperands;
  47. for (auto I : seq<unsigned>(0, NamedNode->getNumOperands())) {
  48. if (O.shouldKeep())
  49. KeptOperands.push_back(NamedNode->getOperand(I));
  50. else
  51. MadeChange = true;
  52. }
  53. if (MadeChange) {
  54. NamedNode->clearOperands();
  55. for (MDNode *KeptOperand : KeptOperands)
  56. NamedNode->addOperand(KeptOperand);
  57. }
  58. }
  59. }
  60. /// Removes all the Named and Unnamed Metadata Nodes, as well as any debug
  61. /// functions that aren't inside the desired Chunks.
  62. static void extractMetadataFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
  63. Module &Program = WorkItem.getModule();
  64. // Get out-of-chunk Named metadata nodes
  65. SmallVector<NamedMDNode *> NamedNodesToDelete;
  66. for (NamedMDNode &MD : Program.named_metadata())
  67. if (!shouldKeepDebugNamedMetadata(MD) && !O.shouldKeep())
  68. NamedNodesToDelete.push_back(&MD);
  69. for (NamedMDNode *NN : NamedNodesToDelete) {
  70. for (auto I : seq<unsigned>(0, NN->getNumOperands()))
  71. NN->setOperand(I, nullptr);
  72. NN->eraseFromParent();
  73. }
  74. // Delete out-of-chunk metadata attached to globals.
  75. for (GlobalVariable &GV : Program.globals()) {
  76. SmallVector<std::pair<unsigned, MDNode *>> MDs;
  77. GV.getAllMetadata(MDs);
  78. for (std::pair<unsigned, MDNode *> &MD : MDs)
  79. if (!O.shouldKeep())
  80. GV.setMetadata(MD.first, nullptr);
  81. }
  82. for (Function &F : Program) {
  83. {
  84. SmallVector<std::pair<unsigned, MDNode *>> MDs;
  85. // Delete out-of-chunk metadata attached to functions.
  86. F.getAllMetadata(MDs);
  87. for (std::pair<unsigned, MDNode *> &MD : MDs)
  88. if (!O.shouldKeep())
  89. F.setMetadata(MD.first, nullptr);
  90. }
  91. // Delete out-of-chunk metadata attached to instructions.
  92. for (Instruction &I : instructions(F)) {
  93. SmallVector<std::pair<unsigned, MDNode *>> MDs;
  94. I.getAllMetadata(MDs);
  95. for (std::pair<unsigned, MDNode *> &MD : MDs) {
  96. if (!shouldKeepDebugIntrinsicMetadata(I, *MD.second) && !O.shouldKeep())
  97. I.setMetadata(MD.first, nullptr);
  98. }
  99. }
  100. }
  101. }
  102. void llvm::reduceMetadataDeltaPass(TestRunner &Test) {
  103. runDeltaPass(Test, extractMetadataFromModule, "Reducing Metadata");
  104. }
  105. void llvm::reduceNamedMetadataDeltaPass(TestRunner &Test) {
  106. runDeltaPass(Test, reduceNamedMetadataOperands, "Reducing Named Metadata");
  107. }