Skip to content

Commit

Permalink
[Metarenamer] Introduce option to only change inst names
Browse files Browse the repository at this point in the history
This is useful when needing to modify IR and test some optimizations on
them, while keeping BB names and function names intact. If
the IR uses ordered number naming (%1, %2, %3 etc), then we cannot just
remove or reorder specific instructions since the verifier expects the
numbers to be in order.
  • Loading branch information
annamthomas committed Jun 30, 2023
1 parent a5ea676 commit 6f9e743
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 8 deletions.
42 changes: 34 additions & 8 deletions llvm/lib/Transforms/Utils/MetaRenamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Type.h"
Expand Down Expand Up @@ -59,6 +60,11 @@ static cl::opt<std::string> RenameExcludeStructPrefixes(
"by a comma"),
cl::Hidden);

static cl::opt<bool>
RenameOnlyInst("rename-only-inst", cl::init(false),
cl::desc("only rename the instructions in the function"),
cl::Hidden);

static const char *const metaNames[] = {
// See http://en.wikipedia.org/wiki/Metasyntactic_variable
"foo", "bar", "baz", "quux", "barney", "snork", "zot", "blam", "hoge",
Expand Down Expand Up @@ -102,6 +108,12 @@ parseExcludedPrefixes(StringRef PrefixesStr,
}
}

void MetaRenameOnlyInstructions(Function &F) {
for (auto &I : instructions(F))
if (!I.getType()->isVoidTy())
I.setName(I.getOpcodeName());
}

void MetaRename(Function &F) {
for (Argument &Arg : F.args())
if (!Arg.getType()->isVoidTy())
Expand Down Expand Up @@ -142,6 +154,26 @@ void MetaRename(Module &M,
[&Name](auto &Prefix) { return Name.startswith(Prefix); });
};

// Leave library functions alone because their presence or absence could
// affect the behavior of other passes.
auto ExcludeLibFuncs = [&](Function &F) {
LibFunc Tmp;
StringRef Name = F.getName();
return Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
GetTLI(F).getLibFunc(F, Tmp) ||
IsNameExcluded(Name, ExcludedFuncPrefixes);
};

if (RenameOnlyInst) {
// Rename all functions
for (auto &F : M) {
if (ExcludeLibFuncs(F))
continue;
MetaRenameOnlyInstructions(F);
}
return;
}

// Rename all aliases
for (GlobalAlias &GA : M.aliases()) {
StringRef Name = GA.getName();
Expand Down Expand Up @@ -178,18 +210,12 @@ void MetaRename(Module &M,

// Rename all functions
for (auto &F : M) {
StringRef Name = F.getName();
LibFunc Tmp;
// Leave library functions alone because their presence or absence could
// affect the behavior of other passes.
if (Name.startswith("llvm.") || (!Name.empty() && Name[0] == 1) ||
GetTLI(F).getLibFunc(F, Tmp) ||
IsNameExcluded(Name, ExcludedFuncPrefixes))
if (ExcludeLibFuncs(F))
continue;

// Leave @main alone. The output of -metarenamer might be passed to
// lli for execution and the latter needs a main entry point.
if (Name != "main")
if (F.getName() != "main")
F.setName(renamer.newName());

MetaRename(F);
Expand Down
30 changes: 30 additions & 0 deletions llvm/test/Transforms/MetaRenamer/only-inst.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
; RUN: opt -passes=metarenamer -rename-only-inst=1 -S < %s | FileCheck %s
target triple = "x86_64-pc-linux-gnu"

; CHECK: %struct.foo_xxx = type { i32, float, %struct.bar_xxx }
; CHECK: %struct.bar_xxx = type { i32, double }
%struct.bar_xxx = type { i32, double }
%struct.foo_xxx = type { i32, float, %struct.bar_xxx }

; CHECK: @global_3_xxx = common global
@global_3_xxx = common global i32 0, align 4

; CHECK-LABEL: func_4_xxx
; CHECK-NOT: %1
; CHECK-NOT: %2
; CHECK-NOT: %3
; CHECK-NOT: %4
define void @func_4_xxx(ptr sret(%struct.foo_xxx) %agg.result) nounwind uwtable ssp {
%1 = alloca %struct.foo_xxx, align 8
store i32 1, ptr %1, align 4
%2 = getelementptr inbounds %struct.foo_xxx, ptr %1, i32 0, i32 1
store float 2.000000e+00, ptr %2, align 4
%3 = getelementptr inbounds %struct.foo_xxx, ptr %1, i32 0, i32 2
store i32 3, ptr %3, align 4
%4 = getelementptr inbounds %struct.bar_xxx, ptr %3, i32 0, i32 1
store double 4.000000e+00, ptr %4, align 8
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %agg.result, ptr align 8 %1, i64 24, i1 false)
ret void
}

declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind

0 comments on commit 6f9e743

Please sign in to comment.