20#define DEBUG_TYPE "forceattrs"
25 "Add an attribute to a function. This can be a "
26 "pair of 'function-name:attribute-name', to apply an attribute to a "
27 "specific function. For "
28 "example -force-attribute=foo:noinline. Specifying only an attribute "
29 "will apply the attribute to every function in the module. This "
30 "option can be specified multiple times."));
34 cl::desc(
"Remove an attribute from a function. This can be a "
35 "pair of 'function-name:attribute-name' to remove an attribute "
36 "from a specific function. For "
37 "example -force-remove-attribute=foo:noinline. Specifying only an "
38 "attribute will remove the attribute from all functions in the "
40 "option can be specified multiple times."));
44 case Attribute::AlwaysInline:
45 return F.hasFnAttribute(Attribute::NoInline);
47 case Attribute::NoInline:
48 return F.hasFnAttribute(Attribute::AlwaysInline);
50 case Attribute::OptimizeNone:
51 return F.hasFnAttribute(Attribute::MinSize) ||
52 F.hasFnAttribute(Attribute::OptimizeForSize) ||
53 F.hasFnAttribute(Attribute::OptimizeForDebugging);
55 case Attribute::MinSize:
56 return F.hasFnAttribute(Attribute::OptimizeNone) ||
57 F.hasFnAttribute(Attribute::OptimizeForDebugging);
59 case Attribute::OptimizeForSize:
60 return F.hasFnAttribute(Attribute::OptimizeNone) ||
61 F.hasFnAttribute(Attribute::OptimizeForDebugging);
63 case Attribute::OptimizeForDebugging:
64 return F.hasFnAttribute(Attribute::OptimizeNone) ||
65 F.hasFnAttribute(Attribute::MinSize) ||
66 F.hasFnAttribute(Attribute::OptimizeForSize);
78 auto ParseFunctionAndAttr = [&](
StringRef S) {
80 if (S.contains(
':')) {
82 if (KV.first !=
F.getName())
84 AttributeText = KV.second;
91 <<
" unknown or not a function attribute!\n");
97 auto Kind = ParseFunctionAndAttr(S);
105 auto Kind = ParseFunctionAndAttr(S);
108 F.removeFnAttr(Kind);
120 if (!Opts.forceattrs_csv_path.empty()) {
122 if (!BufferOrError) {
123 std::error_code EC = BufferOrError.getError();
124 M.getContext().emitError(
"cannot open CSV file: " + EC.message());
128 StringRef Buffer = BufferOrError.get()->getBuffer();
132 auto SplitPair = It->
split(
',');
133 if (SplitPair.second.empty())
135 Function *Func = M.getFunction(SplitPair.first);
137 if (Func->isDeclaration())
139 auto SecondSplitPair = SplitPair.second.split(
'=');
140 if (!SecondSplitPair.second.empty()) {
141 Func->addFnAttr(SecondSplitPair.first, SecondSplitPair.second);
150 Func->addFnAttr(AttrKind);
153 errs() <<
"Cannot add " << SplitPair.second
154 <<
" as an attribute name.\n";
158 <<
" does not exist.\n";
static void forceAttributes(Function &F)
If F has any forced attributes given on the command line, add them.
static bool hasConflictingFnAttr(Attribute::AttrKind Kind, Function &F)
static bool hasForceAttributes()
static cl::list< std::string > ForceAttributes("force-attribute", cl::Hidden, cl::desc("Add an attribute to a function. This can be a " "pair of 'function-name:attribute-name', to apply an attribute to a " "specific function. For " "example -force-attribute=foo:noinline. Specifying only an attribute " "will apply the attribute to every function in the module. This " "option can be specified multiple times."))
static cl::list< std::string > ForceRemoveAttributes("force-remove-attribute", cl::Hidden, cl::desc("Remove an attribute from a function. This can be a " "pair of 'function-name:attribute-name' to remove an attribute " "from a specific function. For " "example -force-remove-attribute=foo:noinline. Specifying only an " "attribute will remove the attribute from all functions in the " "module. This " "option can be specified multiple times."))
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Module.h This file contains the declarations for the Module class.
static LLVM_ABI Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
static LLVM_ABI bool canUseAsFnAttr(AttrKind Kind)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
@ None
No attributes have been set.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
A forward iterator which reads text lines from a buffer.
int64_t line_number() const
Return the current line number. May return any number at EOF.
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
This is an optimization pass for GlobalISel generic memory operations.
const IPOOptions & getIPOOptions(const LLVMContext &C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &)