[llvm] 03640ee - [llvm-reduce] Reducing attributes

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 9 13:11:19 PDT 2020


Author: Roman Lebedev
Date: 2020-07-09T23:10:43+03:00
New Revision: 03640ee0fa73c6eaf8cb12050203027239136789

URL: https://github.com/llvm/llvm-project/commit/03640ee0fa73c6eaf8cb12050203027239136789
DIFF: https://github.com/llvm/llvm-project/commit/03640ee0fa73c6eaf8cb12050203027239136789.diff

LOG: [llvm-reduce] Reducing attributes

Summary:
This handles all three places where attributes could currently be - `GlobalVariable`, `Function` and `CallBase`.
For last two, it correctly handles all three possible attribute locations (return value, arguments and function itself)

There was a previous attempt at it D73853,
which was committed in rGfc62b36a000681c01e993242b583c5ec4ab48a3c,
but then reverted all the way back in rGb12176d2aafa0ccb2585aa218fc3b454ba84f2a9
due to some (osx?) test failures.

Reviewers: nickdesaulniers, dblaikie, diegotf, george.burgess.iv, jdoerfert, Tyker, arsenm

Reviewed By: nickdesaulniers

Subscribers: wdng, MaskRay, arsenm, llvm-commits, mgorny

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D83351

Added: 
    llvm/test/Reduce/remove-attributes-from-intrinsic-like-functions.ll
    llvm/test/Reduce/remove-attributes-from-intrinsics.ll
    llvm/test/Reduce/remove-call-site-attributes.ll
    llvm/test/Reduce/remove-function-attributes.ll
    llvm/test/Reduce/remove-global-variable-attributes.ll
    llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp
    llvm/tools/llvm-reduce/deltas/ReduceAttributes.h

Modified: 
    llvm/tools/llvm-reduce/CMakeLists.txt
    llvm/tools/llvm-reduce/DeltaManager.h
    llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn

Removed: 
    


################################################################################
diff  --git a/llvm/test/Reduce/remove-attributes-from-intrinsic-like-functions.ll b/llvm/test/Reduce/remove-attributes-from-intrinsic-like-functions.ll
new file mode 100644
index 000000000000..60df12e94feb
--- /dev/null
+++ b/llvm/test/Reduce/remove-attributes-from-intrinsic-like-functions.ll
@@ -0,0 +1,40 @@
+; Just because a function is named like an intrinsic does not mean we should skip it's attributes.
+;
+; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s
+
+; CHECK-ALL: declare i32 @llvm.not.really.an.intrinsic(i32, i32) #0
+declare i32 @llvm.not.really.an.intrinsic(i32, i32) #0
+
+define i32 @t(i32 %a) {
+; CHECK-ALL-LABEL: @t(
+
+; CHECK-INTERESTINGNESS: %r =
+; CHECK-INTERESTINGNESS-SAME: call
+; CHECK-INTERESTINGNESS-SAME: "arg0"
+; CHECK-INTERESTINGNESS-SAME: i32 @llvm.not.really.an.intrinsic(i32
+; CHECK-INTERESTINGNESS-SAME: "arg3"
+; CHECK-INTERESTINGNESS-SAME: %a
+; CHECK-INTERESTINGNESS-SAME: i32
+; CHECK-INTERESTINGNESS-SAME: %a
+; CHECK-INTERESTINGNESS-SAME: #1
+
+; CHECK-FINAL: %r = call "arg0" i32 @llvm.not.really.an.intrinsic(i32 "arg3" %a, i32 %a) #1
+; CHECK-ALL: ret i32 %r
+
+  %r = call "arg0" "arg1" i32 @llvm.not.really.an.intrinsic(i32 "arg2" "arg3" %a, i32 %a) "arg4" "arg5"
+  ret i32 %r
+}
+
+; CHECK-INTERESTINGNESS: attributes #0 = {
+; CHECK-INTERESTINGNESS-SAME: "arg6"
+
+; CHECK-INTERESTINGNESS: attributes #1 = {
+; CHECK-INTERESTINGNESS-SAME: "arg4"
+
+; CHECK-FINAL: attributes #0 = { "arg6" }
+; CHECK-FINAL: attributes #1 = { "arg4" }
+
+; CHECK-ALL-NOT: attributes #
+
+attributes #0 = { "arg6" "arg7" }

diff  --git a/llvm/test/Reduce/remove-attributes-from-intrinsics.ll b/llvm/test/Reduce/remove-attributes-from-intrinsics.ll
new file mode 100644
index 000000000000..7a8a8f0eb114
--- /dev/null
+++ b/llvm/test/Reduce/remove-attributes-from-intrinsics.ll
@@ -0,0 +1,38 @@
+; We can't actually put attributes on intrinsic declarations, only on call sites.
+;
+; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s
+
+define i32 @t(i32 %a) {
+; CHECK-ALL-LABEL: @t(
+
+; CHECK-INTERESTINGNESS: %r =
+; CHECK-INTERESTINGNESS-SAME: call
+; CHECK-INTERESTINGNESS-SAME: "arg0"
+; CHECK-INTERESTINGNESS-SAME: i32 @llvm.uadd.sat.i32(i32
+; CHECK-INTERESTINGNESS-SAME: "arg3"
+; CHECK-INTERESTINGNESS-SAME: %a
+; CHECK-INTERESTINGNESS-SAME: i32
+; CHECK-INTERESTINGNESS-SAME: %a
+; CHECK-INTERESTINGNESS-SAME: #1
+
+; CHECK-FINAL: %r = call "arg0" i32 @llvm.uadd.sat.i32(i32 "arg3" %a, i32 %a) #1
+; CHECK-ALL: ret i32 %r
+
+  %r = call "arg0" "arg1" i32 @llvm.uadd.sat.i32(i32 "arg2" "arg3" %a, i32 %a) "arg4" "arg5"
+  ret i32 %r
+}
+
+; CHECK-ALL: declare i32 @llvm.uadd.sat.i32(i32, i32) #0
+declare i32 @llvm.uadd.sat.i32(i32, i32) #0
+
+; CHECK-ALL: attributes #0 = { nounwind readnone speculatable willreturn }
+
+; CHECK-INTERESTINGNESS: attributes #1 = {
+; CHECK-INTERESTINGNESS-SAME: "arg4"
+
+; CHECK-FINAL: attributes #1 = { "arg4" }
+
+; CHECK-ALL-NOT: attributes #
+
+attributes #0 = { "arg6" "arg7" }

diff  --git a/llvm/test/Reduce/remove-call-site-attributes.ll b/llvm/test/Reduce/remove-call-site-attributes.ll
new file mode 100644
index 000000000000..e8f50355812a
--- /dev/null
+++ b/llvm/test/Reduce/remove-call-site-attributes.ll
@@ -0,0 +1,38 @@
+; Test that llvm-reduce can remove uninteresting operand bundles from calls.
+;
+; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s
+
+; CHECK-ALL: declare i32 @f1(i32, i32)
+declare i32 @f1(i32, i32)
+
+; CHECK-FINAL-LABEL: define i32 @interesting(i32 %arg0, i32 %arg1) {
+; CHECK-FINAL-NEXT:  entry:
+; CHECK-FINAL-NEXT:    %r = call "attr0" i32 @f1(i32 "attr4" %arg0, i32 %arg1) #0
+; CHECK-FINAL-NEXT:    ret i32 %r
+; CHECK-FINAL-NEXT:  }
+define i32 @interesting(i32 %arg0, i32 %arg1) {
+entry:
+; CHECK-INTERESTINGNESS-LABEL: @interesting(
+
+; CHECK-INTERESTINGNESS: %r = call
+; CHECK-INTERESTINGNESS-SAME: "attr0"
+; CHECK-INTERESTINGNESS-SAME: i32 @f1(
+; CHECK-INTERESTINGNESS-SAME: i32
+; CHECK-INTERESTINGNESS-SAME: "attr4"
+; CHECK-INTERESTINGNESS-SAME: %arg0
+; CHECK-INTERESTINGNESS-SAME: i32
+; CHECK-INTERESTINGNESS-SAME: %arg1
+; CHECK-INTERESTINGNESS-SAME: #0
+; CHECK-INTERESTINGNESS: ret i32 %r
+
+  %r = call "attr0" "attr1" "attr2" i32 @f1(i32 "attr3" "attr4" "attr5" %arg0, i32 "attr6" "attr7" "attr8" %arg1) #0
+  ret i32 %r
+}
+
+; CHECK-INTERESTINGNESS: attributes #0 = {
+; CHECK-INTERESTINGNESS-SAME: "attr10"
+
+; CHECK-FINAL:  attributes #0 = { "attr10" }
+
+attributes #0 = { "attr9" "attr10" "attr11" }

diff  --git a/llvm/test/Reduce/remove-function-attributes.ll b/llvm/test/Reduce/remove-function-attributes.ll
new file mode 100644
index 000000000000..52bbda36f332
--- /dev/null
+++ b/llvm/test/Reduce/remove-function-attributes.ll
@@ -0,0 +1,23 @@
+; Test that llvm-reduce can remove uninteresting attributes.
+;
+; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s
+
+; CHECK-INTERESTINGNESS: declare
+; CHECK-INTERESTINGNESS-SAME: "attr0"
+; CHECK-INTERESTINGNESS-SAME: void @f0
+; CHECK-INTERESTINGNESS-SAME: i32
+; CHECK-INTERESTINGNESS-SAME: i32
+; CHECK-INTERESTINGNESS-SAME: "attr6"
+; CHECK-INTERESTINGNESS-SAME: #0
+
+; CHECK-FINAL: declare "attr0" void @f0(i32, i32 "attr6") #0
+
+declare "attr0" "attr1" "attr2" void @f0(i32 "attr3" "attr4" "attr5", i32 "attr6" "attr7" "attr8") #0
+
+; CHECK-INTERESTINGNESS: attributes #0 = {
+; CHECK-INTERESTINGNESS-SAME: "attr10"
+
+; CHECK-FINAL:  attributes #0 = { "attr10" }
+
+attributes #0 = { "attr9" "attr10" "attr11" }

diff  --git a/llvm/test/Reduce/remove-global-variable-attributes.ll b/llvm/test/Reduce/remove-global-variable-attributes.ll
new file mode 100644
index 000000000000..bec3afd960e9
--- /dev/null
+++ b/llvm/test/Reduce/remove-global-variable-attributes.ll
@@ -0,0 +1,27 @@
+; Test that llvm-reduce can remove uninteresting attributes.
+;
+; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s
+
+; CHECK-ALL: @gv0 = global i32 0 #0
+; CHECK-ALL-NEXT: @gv1 = global i32 0 #1
+; CHECK-ALL-NEXT: @gv2 = global i32 0
+ at gv0 = global i32 0 #0
+ at gv1 = global i32 0 #1
+ at gv2 = global i32 0 #2
+
+; CHECK-INTERESTINGNESS: attributes #0 = {
+; CHECK-INTERESTINGNESS-SAME: "attr0"
+; CHECK-INTERESTINGNESS-SAME: "attr2"
+
+; CHECK-INTERESTINGNESS-NEXT: attributes #1 = {
+; CHECK-INTERESTINGNESS-SAME: "attr4"
+
+; CHECK-FINAL:  attributes #0 = { "attr0" "attr2" }
+; CHECK-FINAL-NEXT:  attributes #1 = { "attr4" }
+
+; CHECK-FINAL-NOT:  attributes #2
+
+attributes #0 = { "attr0" "attr1" "attr2"}
+attributes #1 = { "attr3" "attr4" "attr5"}
+attributes #2 = { "attr6" "attr7" "attr8"}

diff  --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt
index 24eedac613f5..01b9d0b4afe1 100644
--- a/llvm/tools/llvm-reduce/CMakeLists.txt
+++ b/llvm/tools/llvm-reduce/CMakeLists.txt
@@ -14,6 +14,7 @@ add_llvm_tool(llvm-reduce
   TestRunner.cpp
   deltas/Delta.cpp
   deltas/ReduceArguments.cpp
+  deltas/ReduceAttributes.cpp
   deltas/ReduceBasicBlocks.cpp
   deltas/ReduceFunctions.cpp
   deltas/ReduceGlobalVars.cpp

diff  --git a/llvm/tools/llvm-reduce/DeltaManager.h b/llvm/tools/llvm-reduce/DeltaManager.h
index 5635352b43d8..b1a4ee0df4db 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.h
+++ b/llvm/tools/llvm-reduce/DeltaManager.h
@@ -14,6 +14,7 @@
 #include "TestRunner.h"
 #include "deltas/Delta.h"
 #include "deltas/ReduceArguments.h"
+#include "deltas/ReduceAttributes.h"
 #include "deltas/ReduceBasicBlocks.h"
 #include "deltas/ReduceFunctions.h"
 #include "deltas/ReduceGlobalVars.h"
@@ -32,6 +33,7 @@ inline void runDeltaPasses(TestRunner &Tester) {
   reduceArgumentsDeltaPass(Tester);
   reduceInstructionsDeltaPass(Tester);
   reduceOperandBundesDeltaPass(Tester);
+  reduceAttributesDeltaPass(Tester);
   // TODO: Implement the remaining Delta Passes
 }
 

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp b/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp
new file mode 100644
index 000000000000..cbaf5d5efd34
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceAttributes.cpp
@@ -0,0 +1,200 @@
+//===- ReduceAttributes.cpp - Specialized Delta Pass -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a function which calls the Generic Delta pass in order
+// to reduce uninteresting attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceAttributes.h"
+#include "Delta.h"
+#include "TestRunner.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+class LLVMContext;
+} // namespace llvm
+
+using namespace llvm;
+
+namespace {
+
+using AttrPtrVecTy = std::vector<const Attribute *>;
+using AttrPtrIdxVecVecTy = std::pair<unsigned, AttrPtrVecTy>;
+using AttrPtrVecVecTy = SmallVector<AttrPtrIdxVecVecTy, 3>;
+
+/// Given ChunksToKeep, produce a map of global variables/functions/calls
+/// and indexes of attributes to be preserved for each of them.
+class AttributeRemapper : public InstVisitor<AttributeRemapper> {
+  Oracle O;
+
+public:
+  DenseMap<GlobalVariable *, AttrPtrVecTy> GlobalVariablesToRefine;
+  DenseMap<Function *, AttrPtrVecVecTy> FunctionsToRefine;
+  DenseMap<CallBase *, AttrPtrVecVecTy> CallsToRefine;
+
+  explicit AttributeRemapper(ArrayRef<Chunk> ChunksToKeep) : O(ChunksToKeep) {}
+
+  void visitModule(Module &M) {
+    for (GlobalVariable &GV : M.getGlobalList())
+      visitGlobalVariable(GV);
+  }
+
+  void visitGlobalVariable(GlobalVariable &GV) {
+    // Global variables only have one attribute set.
+    const AttributeSet &AS = GV.getAttributes();
+    if (AS.hasAttributes())
+      visitAttributeSet(AS, GlobalVariablesToRefine[&GV]);
+  }
+
+  void visitFunction(Function &F) {
+    if (F.getIntrinsicID() != Intrinsic::not_intrinsic)
+      return; // We can neither add nor remove attributes from intrinsics.
+    visitAttributeList(F.getAttributes(), FunctionsToRefine[&F]);
+  }
+
+  void visitCallBase(CallBase &I) {
+    visitAttributeList(I.getAttributes(), CallsToRefine[&I]);
+  }
+
+  void visitAttributeList(const AttributeList &AL,
+                          AttrPtrVecVecTy &AttributeSetsToPreserve) {
+    assert(AttributeSetsToPreserve.empty() && "Should not be sharing vectors.");
+    AttributeSetsToPreserve.reserve(AL.getNumAttrSets());
+    for (unsigned SetIdx : seq(AL.index_begin(), AL.index_end())) {
+      AttrPtrIdxVecVecTy AttributesToPreserve;
+      AttributesToPreserve.first = SetIdx;
+      visitAttributeSet(AL.getAttributes(AttributesToPreserve.first),
+                        AttributesToPreserve.second);
+      if (!AttributesToPreserve.second.empty())
+        AttributeSetsToPreserve.emplace_back(std::move(AttributesToPreserve));
+    }
+  }
+
+  void visitAttributeSet(const AttributeSet &AS,
+                         AttrPtrVecTy &AttrsToPreserve) {
+    assert(AttrsToPreserve.empty() && "Should not be sharing vectors.");
+    AttrsToPreserve.reserve(AS.getNumAttributes());
+    for (const Attribute &A : AS)
+      if (O.shouldKeep())
+        AttrsToPreserve.emplace_back(&A);
+  }
+};
+
+struct AttributeCounter : public InstVisitor<AttributeCounter> {
+  /// How many features (in this case, attributes) did we count, total?
+  int AttributeCount = 0;
+
+  void visitModule(Module &M) {
+    for (GlobalVariable &GV : M.getGlobalList())
+      visitGlobalVariable(GV);
+  }
+
+  void visitGlobalVariable(GlobalVariable &GV) {
+    // Global variables only have one attribute set.
+    visitAttributeSet(GV.getAttributes());
+  }
+
+  void visitFunction(Function &F) {
+    if (F.getIntrinsicID() != Intrinsic::not_intrinsic)
+      return; // We can neither add nor remove attributes from intrinsics.
+    visitAttributeList(F.getAttributes());
+  }
+
+  void visitCallBase(CallBase &I) { visitAttributeList(I.getAttributes()); }
+
+  void visitAttributeList(const AttributeList &AL) {
+    for (const AttributeSet &AS : AL)
+      visitAttributeSet(AS);
+  }
+
+  void visitAttributeSet(const AttributeSet &AS) {
+    AttributeCount += AS.getNumAttributes();
+  }
+};
+
+} // namespace
+
+AttributeSet
+convertAttributeRefToAttributeSet(LLVMContext &C,
+                                  ArrayRef<const Attribute *> Attributes) {
+  AttrBuilder B;
+  for (const Attribute *A : Attributes)
+    B.addAttribute(*A);
+  return AttributeSet::get(C, B);
+}
+
+AttributeList convertAttributeRefVecToAttributeList(
+    LLVMContext &C, ArrayRef<AttrPtrIdxVecVecTy> AttributeSets) {
+  std::vector<std::pair<unsigned, AttributeSet>> SetVec;
+  SetVec.reserve(AttributeSets.size());
+
+  transform(AttributeSets, std::back_inserter(SetVec),
+            [&C](const AttrPtrIdxVecVecTy &V) {
+              return std::make_pair(
+                  V.first, convertAttributeRefToAttributeSet(C, V.second));
+            });
+
+  sort(SetVec, [](const std::pair<unsigned, AttributeSet> &LHS,
+                  const std::pair<unsigned, AttributeSet> &RHS) {
+    return LHS.first < RHS.first; // All values are unique.
+  });
+
+  return AttributeList::get(C, SetVec);
+}
+
+/// Removes out-of-chunk attributes from module.
+static void extractAttributesFromModule(std::vector<Chunk> ChunksToKeep,
+                                        Module *Program) {
+  AttributeRemapper R(ChunksToKeep);
+  R.visit(Program);
+
+  LLVMContext &C = Program->getContext();
+  for (const auto &I : R.GlobalVariablesToRefine)
+    I.first->setAttributes(convertAttributeRefToAttributeSet(C, I.second));
+  for (const auto &I : R.FunctionsToRefine)
+    I.first->setAttributes(convertAttributeRefVecToAttributeList(C, I.second));
+  for (const auto &I : R.CallsToRefine)
+    I.first->setAttributes(convertAttributeRefVecToAttributeList(C, I.second));
+}
+
+/// Counts the amount of attributes.
+static int countAttributes(Module *Program) {
+  AttributeCounter C;
+
+  // TODO: Silence index with --quiet flag
+  outs() << "----------------------------\n";
+  C.visit(Program);
+  outs() << "Number of attributes: " << C.AttributeCount << "\n";
+
+  return C.AttributeCount;
+}
+
+void llvm::reduceAttributesDeltaPass(TestRunner &Test) {
+  outs() << "*** Reducing Attributes...\n";
+  int AttributeCount = countAttributes(Test.getProgram());
+  runDeltaPass(Test, AttributeCount, extractAttributesFromModule);
+}

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceAttributes.h b/llvm/tools/llvm-reduce/deltas/ReduceAttributes.h
new file mode 100644
index 000000000000..f8deb045560f
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceAttributes.h
@@ -0,0 +1,20 @@
+//===- ReduceAttributes.h - Specialized Delta Pass ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a function which calls the Generic Delta pass in order
+// to reduce uninteresting attributes.
+//
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+class TestRunner;
+
+void reduceAttributesDeltaPass(TestRunner &Test);
+
+} // namespace llvm

diff  --git a/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn
index efb8e40850c3..a8648d73ca0d 100644
--- a/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn
@@ -12,6 +12,7 @@ executable("llvm-reduce") {
     "TestRunner.cpp",
     "deltas/Delta.cpp",
     "deltas/ReduceArguments.cpp",
+    "deltas/ReduceAttributes.cpp",
     "deltas/ReduceBasicBlocks.cpp",
     "deltas/ReduceFunctions.cpp",
     "deltas/ReduceGlobalVars.cpp",


        


More information about the llvm-commits mailing list