[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