[llvm] r256465 - [attrs] Split off the forced attributes utility into its own pass that

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 27 00:13:46 PST 2015


Author: chandlerc
Date: Sun Dec 27 02:13:45 2015
New Revision: 256465

URL: http://llvm.org/viewvc/llvm-project?rev=256465&view=rev
Log:
[attrs] Split off the forced attributes utility into its own pass that
is (by default) run much earlier than FuncitonAttrs proper.

This allows forcing optnone or other widely impactful attributes. It is
also a bit simpler as the force attribute behavior needs no specific
iteration order.

I've added the pass into the default module pass pipeline and LTO pass
pipeline which mirrors where function attrs itself was being run.

Differential Revision: http://reviews.llvm.org/D15668

Added:
    llvm/trunk/include/llvm/Transforms/IPO/ForceFunctionAttrs.h
    llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp
    llvm/trunk/test/Transforms/ForcedFunctionAttrs/
    llvm/trunk/test/Transforms/ForcedFunctionAttrs/forced.ll
Removed:
    llvm/trunk/test/Transforms/FunctionAttrs/forced.ll
Modified:
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/lib/Passes/PassBuilder.cpp
    llvm/trunk/lib/Passes/PassRegistry.def
    llvm/trunk/lib/Transforms/IPO/CMakeLists.txt
    llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
    llvm/trunk/lib/Transforms/IPO/IPO.cpp
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Sun Dec 27 02:13:45 2015
@@ -131,6 +131,7 @@ void initializeScalarizerPass(PassRegist
 void initializeEarlyCSELegacyPassPass(PassRegistry &);
 void initializeEliminateAvailableExternallyPass(PassRegistry&);
 void initializeExpandISelPseudosPass(PassRegistry&);
+void initializeForceFunctionAttrsLegacyPassPass(PassRegistry&);
 void initializeFunctionAttrsPass(PassRegistry&);
 void initializeGCMachineCodeAnalysisPass(PassRegistry&);
 void initializeGCModuleInfoPass(PassRegistry&);

Added: llvm/trunk/include/llvm/Transforms/IPO/ForceFunctionAttrs.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/ForceFunctionAttrs.h?rev=256465&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Transforms/IPO/ForceFunctionAttrs.h (added)
+++ llvm/trunk/include/llvm/Transforms/IPO/ForceFunctionAttrs.h Sun Dec 27 02:13:45 2015
@@ -0,0 +1,35 @@
+//===-- ForceFunctionAttrs.h - Force function attrs for debugging ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// Super simple passes to force specific function attrs from the commandline
+/// into the IR for debugging purposes.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_FORCEFUNCTIONATTRS_H
+#define LLVM_TRANSFORMS_IPO_FORCEFUNCTIONATTRS_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Pass which forces specific function attributes into the IR, primarily as
+/// a debugging tool.
+class ForceFunctionAttrsPass {
+public:
+  static StringRef name() { return "ForceFunctionAttrsPass"; }
+  PreservedAnalyses run(Module &M);
+};
+
+/// Create a legacy pass manager instance of a pass to force function attrs.
+Pass *createForceFunctionAttrsLegacyPass();
+
+}
+
+#endif // LLVM_TRANSFORMS_IPO_FORCEFUNCTIONATTRS_H

Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Sun Dec 27 02:13:45 2015
@@ -29,13 +29,14 @@
 #include "llvm/IR/Verifier.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/InstCombine/InstCombine.h"
+#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
+#include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Scalar/ADCE.h"
 #include "llvm/Transforms/Scalar/EarlyCSE.h"
 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
-#include "llvm/Transforms/Scalar/SimplifyCFG.h"
 #include "llvm/Transforms/Scalar/SROA.h"
+#include "llvm/Transforms/Scalar/SimplifyCFG.h"
 
 using namespace llvm;
 

Modified: llvm/trunk/lib/Passes/PassRegistry.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/lib/Passes/PassRegistry.def (original)
+++ llvm/trunk/lib/Passes/PassRegistry.def Sun Dec 27 02:13:45 2015
@@ -27,6 +27,7 @@ MODULE_ANALYSIS("targetlibinfo", TargetL
 #ifndef MODULE_PASS
 #define MODULE_PASS(NAME, CREATE_PASS)
 #endif
+MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
 MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
 MODULE_PASS("no-op-module", NoOpModulePass())
 MODULE_PASS("print", PrintModulePass(dbgs()))

Modified: llvm/trunk/lib/Transforms/IPO/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/CMakeLists.txt?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/IPO/CMakeLists.txt Sun Dec 27 02:13:45 2015
@@ -6,6 +6,7 @@ add_llvm_library(LLVMipo
   DeadArgumentElimination.cpp
   ElimAvailExtern.cpp
   ExtractGV.cpp
+  ForceFunctionAttrs.cpp
   FunctionAttrs.cpp
   FunctionImport.cpp
   GlobalDCE.cpp

Added: llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp?rev=256465&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp (added)
+++ llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp Sun Dec 27 02:13:45 2015
@@ -0,0 +1,121 @@
+//===- ForceFunctionAttrs.cpp - Force function attrs for debugging --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "forceattrs"
+
+static cl::list<std::string>
+    ForceAttributes("force-attribute", cl::Hidden,
+                    cl::desc("Add an attribute to a function. This should be a "
+                             "pair of 'function-name:attribute-name', for "
+                             "example -force-add-attribute=foo:noinline. This "
+                             "option can be specified multiple times."));
+
+static Attribute::AttrKind parseAttrKind(StringRef Kind) {
+  return StringSwitch<Attribute::AttrKind>(Kind)
+      .Case("alwaysinline", Attribute::AlwaysInline)
+      .Case("builtin", Attribute::Builtin)
+      .Case("cold", Attribute::Cold)
+      .Case("convergent", Attribute::Convergent)
+      .Case("inlinehint", Attribute::InlineHint)
+      .Case("jumptable", Attribute::JumpTable)
+      .Case("minsize", Attribute::MinSize)
+      .Case("naked", Attribute::Naked)
+      .Case("nobuiltin", Attribute::NoBuiltin)
+      .Case("noduplicate", Attribute::NoDuplicate)
+      .Case("noimplicitfloat", Attribute::NoImplicitFloat)
+      .Case("noinline", Attribute::NoInline)
+      .Case("nonlazybind", Attribute::NonLazyBind)
+      .Case("noredzone", Attribute::NoRedZone)
+      .Case("noreturn", Attribute::NoReturn)
+      .Case("norecurse", Attribute::NoRecurse)
+      .Case("nounwind", Attribute::NoUnwind)
+      .Case("optnone", Attribute::OptimizeNone)
+      .Case("optsize", Attribute::OptimizeForSize)
+      .Case("readnone", Attribute::ReadNone)
+      .Case("readonly", Attribute::ReadOnly)
+      .Case("argmemonly", Attribute::ArgMemOnly)
+      .Case("returns_twice", Attribute::ReturnsTwice)
+      .Case("safestack", Attribute::SafeStack)
+      .Case("sanitize_address", Attribute::SanitizeAddress)
+      .Case("sanitize_memory", Attribute::SanitizeMemory)
+      .Case("sanitize_thread", Attribute::SanitizeThread)
+      .Case("ssp", Attribute::StackProtect)
+      .Case("sspreq", Attribute::StackProtectReq)
+      .Case("sspstrong", Attribute::StackProtectStrong)
+      .Case("uwtable", Attribute::UWTable)
+      .Default(Attribute::None);
+}
+
+/// If F has any forced attributes given on the command line, add them.
+static void addForcedAttributes(Function &F) {
+  for (auto &S : ForceAttributes) {
+    auto KV = StringRef(S).split(':');
+    if (KV.first != F.getName())
+      continue;
+
+    auto Kind = parseAttrKind(KV.second);
+    if (Kind == Attribute::None) {
+      DEBUG(dbgs() << "ForcedAttribute: " << KV.second
+                   << " unknown or not handled!\n");
+      continue;
+    }
+    if (F.hasFnAttribute(Kind))
+      continue;
+    F.addFnAttr(Kind);
+  }
+}
+
+PreservedAnalyses ForceFunctionAttrsPass::run(Module &M) {
+  if (ForceAttributes.empty())
+    return PreservedAnalyses::all();
+
+  for (Function &F : M.functions())
+    addForcedAttributes(F);
+
+  // Just conservatively invalidate analyses, this isn't likely to be important.
+  return PreservedAnalyses::none();
+}
+
+namespace {
+struct ForceFunctionAttrsLegacyPass : public ModulePass {
+  static char ID; // Pass identification, replacement for typeid
+  ForceFunctionAttrsLegacyPass() : ModulePass(ID) {
+    initializeForceFunctionAttrsLegacyPassPass(
+        *PassRegistry::getPassRegistry());
+  }
+
+  bool runOnModule(Module &M) override {
+    if (ForceAttributes.empty())
+      return false;
+
+    for (Function &F : M.functions())
+      addForcedAttributes(F);
+
+    // Conservatively assume we changed something.
+    return true;
+  }
+};
+}
+
+char ForceFunctionAttrsLegacyPass::ID = 0;
+INITIALIZE_PASS(ForceFunctionAttrsLegacyPass, "forceattrs",
+                "Force set function attributes", false, false)
+
+Pass *llvm::createForceFunctionAttrsLegacyPass() {
+  return new ForceFunctionAttrsLegacyPass();
+}

Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Sun Dec 27 02:13:45 2015
@@ -53,13 +53,6 @@ STATISTIC(NumNonNullReturn, "Number of f
 STATISTIC(NumAnnotated, "Number of attributes added to library functions");
 STATISTIC(NumNoRecurse, "Number of functions marked as norecurse");
 
-static cl::list<std::string>
-ForceAttributes("force-attribute", cl::Hidden,
-                cl::desc("Add an attribute to a function. This should be a "
-                         "pair of 'function-name:attribute-name', for "
-                         "example -force-add-attribute=foo:noinline. This "
-                         "option can be specified multiple times."));
-
 namespace {
 typedef SmallSetVector<Function *, 8> SCCNodeSet;
 }
@@ -1851,64 +1844,6 @@ static bool addNoRecurseAttrsTopDownOnly
   return false;
 }
 
-static Attribute::AttrKind parseAttrKind(StringRef Kind) {
-  return StringSwitch<Attribute::AttrKind>(Kind)
-    .Case("alwaysinline", Attribute::AlwaysInline)
-    .Case("builtin", Attribute::Builtin)
-    .Case("cold", Attribute::Cold)
-    .Case("convergent", Attribute::Convergent)
-    .Case("inlinehint", Attribute::InlineHint)
-    .Case("jumptable", Attribute::JumpTable)
-    .Case("minsize", Attribute::MinSize)
-    .Case("naked", Attribute::Naked)
-    .Case("nobuiltin", Attribute::NoBuiltin)
-    .Case("noduplicate", Attribute::NoDuplicate)
-    .Case("noimplicitfloat", Attribute::NoImplicitFloat)
-    .Case("noinline", Attribute::NoInline)
-    .Case("nonlazybind", Attribute::NonLazyBind)
-    .Case("noredzone", Attribute::NoRedZone)
-    .Case("noreturn", Attribute::NoReturn)
-    .Case("norecurse", Attribute::NoRecurse)
-    .Case("nounwind", Attribute::NoUnwind)
-    .Case("optnone", Attribute::OptimizeNone)
-    .Case("optsize", Attribute::OptimizeForSize)
-    .Case("readnone", Attribute::ReadNone)
-    .Case("readonly", Attribute::ReadOnly)
-    .Case("argmemonly", Attribute::ArgMemOnly)
-    .Case("returns_twice", Attribute::ReturnsTwice)
-    .Case("safestack", Attribute::SafeStack)
-    .Case("sanitize_address", Attribute::SanitizeAddress)
-    .Case("sanitize_memory", Attribute::SanitizeMemory)
-    .Case("sanitize_thread", Attribute::SanitizeThread)
-    .Case("ssp", Attribute::StackProtect)
-    .Case("sspreq", Attribute::StackProtectReq)
-    .Case("sspstrong", Attribute::StackProtectStrong)
-    .Case("uwtable", Attribute::UWTable)
-    .Default(Attribute::None);
-}
-
-/// If F has any forced attributes given on the command line, add them.
-static bool addForcedAttributes(Function *F) {
-  bool Changed = false;
-  for (auto &S : ForceAttributes) {
-    auto KV = StringRef(S).split(':');
-    if (KV.first != F->getName())
-      continue;
-
-    auto Kind = parseAttrKind(KV.second);
-    if (Kind == Attribute::None) {
-      DEBUG(dbgs() << "ForcedAttribute: " << KV.second
-                   << " unknown or not handled!\n");
-      continue;
-    }
-    if (F->hasFnAttribute(Kind))
-      continue;
-    Changed = true;
-    F->addFnAttr(Kind);
-  }
-  return Changed;
-}
-
 bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
   TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
   bool Changed = false;
@@ -1944,7 +1879,6 @@ bool FunctionAttrs::runOnSCC(CallGraphSC
     if (F->isDeclaration())
       Changed |= inferPrototypeAttributes(*F, *TLI);
 
-    Changed |= addForcedAttributes(F);
     SCCNodes.insert(F);
   }
 

Modified: llvm/trunk/lib/Transforms/IPO/IPO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/IPO.cpp?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/IPO.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/IPO.cpp Sun Dec 27 02:13:45 2015
@@ -27,6 +27,7 @@ void llvm::initializeIPO(PassRegistry &R
   initializeCrossDSOCFIPass(Registry);
   initializeDAEPass(Registry);
   initializeDAHPass(Registry);
+  initializeForceFunctionAttrsLegacyPassPass(Registry);
   initializeFunctionAttrsPass(Registry);
   initializeGlobalDCEPass(Registry);
   initializeGlobalOptPass(Registry);

Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=256465&r1=256464&r2=256465&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Sun Dec 27 02:13:45 2015
@@ -31,6 +31,7 @@
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Vectorize.h"
 
@@ -187,6 +188,9 @@ void PassManagerBuilder::populateFunctio
 
 void PassManagerBuilder::populateModulePassManager(
     legacy::PassManagerBase &MPM) {
+  // Allow forcing function attributes as a debugging and tuning aid.
+  MPM.add(createForceFunctionAttrsLegacyPass());
+
   // If all optimizations are disabled, just run the always-inline pass and,
   // if enabled, the function merging pass.
   if (OptLevel == 0) {
@@ -483,6 +487,9 @@ void PassManagerBuilder::addLTOOptimizat
   if (FunctionIndex)
     PM.add(createFunctionImportPass(FunctionIndex));
 
+  // Allow forcing function attributes as a debugging and tuning aid.
+  PM.add(createForceFunctionAttrsLegacyPass());
+
   // Propagate constants at call sites into the functions they call.  This
   // opens opportunities for globalopt (and inlining) by substituting function
   // pointers passed as arguments to direct uses of functions.

Added: llvm/trunk/test/Transforms/ForcedFunctionAttrs/forced.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ForcedFunctionAttrs/forced.ll?rev=256465&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ForcedFunctionAttrs/forced.ll (added)
+++ llvm/trunk/test/Transforms/ForcedFunctionAttrs/forced.ll Sun Dec 27 02:13:45 2015
@@ -0,0 +1,12 @@
+; RUN: opt < %s -S -forceattrs | FileCheck %s --check-prefix=CHECK-CONTROL
+; RUN: opt < %s -S -forceattrs -force-attribute foo:noinline | FileCheck %s --check-prefix=CHECK-FOO
+; RUN: opt < %s -S -passes=forceattrs -force-attribute foo:noinline | FileCheck %s --check-prefix=CHECK-FOO
+
+; CHECK-CONTROL: define void @foo() {
+; CHECK-FOO: define void @foo() #0 {
+define void @foo() {
+  ret void
+}
+
+
+; CHECK-FOO: attributes #0 = { noinline }

Removed: llvm/trunk/test/Transforms/FunctionAttrs/forced.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/forced.ll?rev=256464&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/forced.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/forced.ll (removed)
@@ -1,12 +0,0 @@
-; RUN: opt < %s -S -functionattrs | FileCheck %s --check-prefix=CHECK-CONTROL
-; RUN: opt < %s -S -functionattrs -force-attribute foo:noinline | FileCheck %s --check-prefix=CHECK-FOO
-
-; CHECK-CONTROL: define void @foo() #0 {
-; CHECK-FOO: define void @foo() #0 {
-define void @foo() {
-  ret void
-}
-
-
-; CHECK-CONTROL: attributes #0 = { norecurse readnone }
-; CHECK-FOO: attributes #0 = { noinline norecurse readnone }




More information about the llvm-commits mailing list