Skip to content

Commit f42393c

Browse files
authored
Merge pull request #434 from Chun-Ching-Hsu/lab6
[LAB6] 313554033
2 parents 457eb62 + aba1b7f commit f42393c

File tree

1 file changed

+97
-19
lines changed

1 file changed

+97
-19
lines changed

lab6/llvm-pass.so.cc

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,112 @@
1+
// llvm-pass.so.cc
12
#include "llvm/Passes/PassPlugin.h"
23
#include "llvm/Passes/PassBuilder.h"
34
#include "llvm/IR/IRBuilder.h"
4-
5+
#include "llvm/IR/Module.h"
6+
#include "llvm/IR/Function.h"
7+
#include "llvm/IR/Instructions.h"
8+
#include "llvm/IR/Constants.h"
9+
#include <vector>
510
using namespace llvm;
611

7-
struct LLVMPass : public PassInfoMixin<LLVMPass> {
8-
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
9-
};
12+
struct LLVMPass : PassInfoMixin<LLVMPass> {
13+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
14+
LLVMContext &Ctx = M.getContext();
15+
IntegerType *i32Ty = Type::getInt32Ty(Ctx);
16+
PointerType *i8PtrTy= Type::getInt8PtrTy(Ctx);
17+
18+
// 1) debug(int)
19+
FunctionCallee debugFn = M.getOrInsertFunction(
20+
"debug",
21+
FunctionType::get(Type::getVoidTy(Ctx), {i32Ty}, false)
22+
);
23+
Constant *debugArg = ConstantInt::get(i32Ty, 48763);
24+
25+
// 2) 準備常量字串
26+
Constant *strData = ConstantDataArray::getString(
27+
Ctx, "hayaku... motohayaku!", true);
28+
GlobalVariable *gvStr = new GlobalVariable(
29+
M, strData->getType(), true,
30+
GlobalValue::PrivateLinkage, strData, "lab6_str");
31+
Value *strPtr = ConstantExpr::getBitCast(gvStr, i8PtrTy);
32+
33+
// 找 main 函式
34+
if (Function *mainF = M.getFunction("main")) {
35+
// 在 EntryBlock 首個插入點呼叫 debug(48763)
36+
IRBuilder<> B(&*mainF->getEntryBlock().getFirstInsertionPt());
37+
B.CreateCall(debugFn, { debugArg });
38+
39+
// 取出 main(argc, argv) 的參數
40+
Argument *argcArg = nullptr, *argvArg = nullptr;
41+
auto it = mainF->arg_begin();
42+
if (it != mainF->arg_end()) argcArg = &*it++;
43+
if (it != mainF->arg_end()) argvArg = &*it;
44+
45+
// 搜集所有要移除的 LoadInst
46+
std::vector<Instruction*> toErase;
1047

11-
PreservedAnalyses LLVMPass::run(Module &M, ModuleAnalysisManager &MAM) {
12-
LLVMContext &Ctx = M.getContext();
13-
IntegerType *Int32Ty = IntegerType::getInt32Ty(Ctx);
14-
FunctionCallee debug_func = M.getOrInsertFunction("debug", Int32Ty);
15-
ConstantInt *debug_arg = ConstantInt::get(Int32Ty, 48763);
48+
// 遍历所有指令
49+
for (auto &BB : *mainF) {
50+
for (auto &I : BB) {
51+
// (a) 替换所有使用 argcArg 的地方
52+
for (unsigned u = 0; u < I.getNumOperands(); ++u) {
53+
if (I.getOperand(u) == argcArg)
54+
I.setOperand(u, debugArg);
55+
}
1656

17-
for (auto &F : M) {
18-
errs() << "func: " << F.getName() << "\n";
57+
// (b) 找到 load argv[1] 的 LoadInst,替换它的所有使用
1958

59+
if (auto *LI = dyn_cast<LoadInst>(&I)) {
60+
// 把所有 index==1 的 GEP 载入都替换
61+
Value *ptr = LI->getPointerOperand()->stripPointerCasts();
62+
if (auto *G = dyn_cast<GetElementPtrInst>(ptr)) {
63+
if (G->getNumIndices() == 1) {
64+
if (auto *CI = dyn_cast<ConstantInt>(G->getOperand(1))) {
65+
if (CI->equalsInt(1)) {
66+
LI->replaceAllUsesWith(strPtr);
67+
toErase.push_back(LI);
68+
}
69+
}
70+
}
71+
}
72+
}
73+
74+
// (c) 用 arg_size() 替换 strcmp 的第一個參數
75+
if (auto *CI = dyn_cast<CallInst>(&I)) {
76+
if (Function *callee = CI->getCalledFunction()) {
77+
if (callee->getName() == "strcmp" && CI->arg_size() >= 2) {
78+
CI->setArgOperand(0, strPtr);
79+
}
80+
}
81+
}
82+
}
83+
}
84+
85+
// 真正刪除那些已被替換的 LoadInst
86+
for (auto *I : toErase)
87+
I->eraseFromParent();
88+
}
89+
90+
return PreservedAnalyses::none();
2091
}
21-
return PreservedAnalyses::none();
22-
}
92+
};
2393

94+
// 註冊為 LLVM Plugin
2495
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
2596
llvmGetPassPluginInfo() {
26-
return {LLVM_PLUGIN_API_VERSION, "LLVMPass", "1.0",
97+
return {
98+
LLVM_PLUGIN_API_VERSION, "Lab6Pass", "v1.0",
2799
[](PassBuilder &PB) {
28-
PB.registerOptimizerLastEPCallback(
29-
[](ModulePassManager &MPM, OptimizationLevel OL) {
100+
// PB.registerOptimizerLastEPCallback(
101+
// [](ModulePassManager &MPM, OptimizationLevel) {
102+
// MPM.addPass(LLVMPass());
103+
// });
104+
// }
105+
// 無論 -O0 還是 -O1/O2,都在 pipeline 一開始插入 LLVMPass
106+
PB.registerPipelineStartEPCallback(
107+
[](ModulePassManager &MPM, OptimizationLevel) {
30108
MPM.addPass(LLVMPass());
31-
});
32-
}};
109+
});
110+
}
111+
};
33112
}
34-

0 commit comments

Comments
 (0)