Skip to content

Commit e1d0694

Browse files
committed
重构引用函数机制,修复Float计算问题
1 parent 10824e7 commit e1d0694

17 files changed

+354
-92
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,4 @@ message(STATUS "${TIME_MODULE}")
105105
add_library(time "${TIME_MODULE}")
106106

107107
# test.cpp
108-
add_executable(test test/test1.c)
108+
#add_executable(test test/test1.c)

Global.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
/// 特性前缀
4545
#define LabelPrefix "__neuq_kingtous_"
46+
#define FuncPrefix "__sysyplus_"
4647
#define APPNAME "cn.kingtous.sysycompiler"
4748
/// 全局变量
4849
#define HASLOCALS (TheCodeGenContext->get_current_locals() != nullptr)

ast/NodeAST.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ llvm::Value *BinaryExprAST::codegen() {
4040
if (!L || !R)
4141
return nullptr;
4242
// 数值计算
43-
if (L->getType() == getTypeFromStr("int") && R->getType() == getTypeFromStr("int")) {
43+
if (L->getType()->isIntegerTy() && R->getType()->isIntegerTy()) {
4444
switch (type) {
4545
case BinaryType::add:
4646
return Builder.CreateAdd(L, R, "add");
@@ -74,8 +74,8 @@ llvm::Value *BinaryExprAST::codegen() {
7474
// auto boolR = Builder.CreateICmpNE(R,ConstantInt::get(getTypeFromStr("bool"),0));
7575
// Builder.
7676
// return Builder.CreateICmpSLE(boolL, boolR, "less_equ");
77-
// default:
78-
// return LogErrorV(("invalid binary operator"));
77+
default:
78+
return LogErrorV(("invalid binary operator"));
7979
}
8080
} else {
8181
// 类型不相同,做类型转换
@@ -211,16 +211,6 @@ string BinaryExprAST::toString() {
211211
llvm::Value *CallExprAST::codegen() {
212212
// Look up the name in the global module table.
213213
llvm::Function *func = TheModule->getFunction(callName);
214-
if (func == NIL){
215-
func = ExternFunctionLinker::getExternFunc(TheContext,*TheModule,callName);
216-
}
217-
if (!func)
218-
return LogErrorV(("使用了未知的函数:" + callName).c_str());
219-
220-
// If argument mismatch error.
221-
if (func->arg_size() != args.size())
222-
return LogErrorV("Incorrect # arguments passed");
223-
224214
std::vector<llvm::Value *> argsV;
225215
for (unsigned i = 0, e = args.size(); i != e; ++i) {
226216
Value *av = args[i]->codegen();
@@ -230,6 +220,20 @@ llvm::Value *CallExprAST::codegen() {
230220
argsV.push_back(av);
231221
}
232222

223+
if (func == NIL){
224+
auto ev = ExternFunctionLinker::tryHandleFuncCall(TheContext,*TheModule,callName,&argsV);
225+
// Extern直接处理,就直接返回
226+
if (ev){
227+
return ev;
228+
}
229+
}
230+
if (!func)
231+
return LogErrorV(("使用了未知的函数:" + callName).c_str());
232+
233+
// If argument mismatch error.
234+
if (func->arg_size() != args.size())
235+
return LogErrorV("Incorrect # arguments passed");
236+
233237
return Builder.CreateCall(func, argsV, "calltmp");
234238
}
235239

@@ -403,7 +407,8 @@ string ForExprAST::toString() {
403407

404408

405409
const std::string &PrototypeAST::getName() const {
406-
return name;
410+
auto str = FuncPrefix + name;
411+
return move(str);
407412
}
408413

409414
PrototypeAST::PrototypeAST(const string &returnType, const string &name, const vector<VariableDeclarationAST *> &args)

extern/ExternFunctionHandler.cpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
//
2+
// Created by bytedance on 2021/3/4.
3+
//
4+
5+
#include "ExternFunctionHandler.h"
6+
7+
#include "ErrHelper.h"
8+
9+
Value *
10+
EchoFunctionHandler::tryhandle(LLVMContext &context, Module &module, std::string callName, std::vector<Value *> *argV) {
11+
if (callName == "echo" && argV != NIL) {
12+
std::string format_str;
13+
for (auto v : *argV){
14+
if (v->getType()->isIntegerTy()){
15+
switch (dyn_cast<IntegerType>(v->getType())->getBitWidth()) {
16+
case 32 :
17+
format_str.append("%d");
18+
break;
19+
case 64:
20+
format_str.append("%ld");
21+
break;
22+
default:
23+
format_str.append("%d");
24+
}
25+
}
26+
else if (v->getType()->isPointerTy() && v->getType()->getContainedType(0)->isIntegerTy(8)){
27+
// 字符数组
28+
format_str.append("%s");
29+
} else {
30+
// not implemented
31+
return LogErrorV(("打印函数的参数无法理解:"+v->getName()).str().c_str());
32+
}
33+
format_str.append(" ");
34+
}
35+
format_str.append("\n");
36+
auto symbol_value = ConstantDataArray::getString(context,format_str);
37+
auto symbol_mem = Builder.CreateAlloca(symbol_value->getType());
38+
Builder.CreateStore(symbol_value,symbol_mem);
39+
auto symbol_pointer = Builder.CreateInBoundsGEP(symbol_mem,
40+
{ConstantInt::get(Type::getInt32Ty(context),0),
41+
ConstantInt::get(Type::getInt32Ty(context),0)});
42+
argV->insert(argV->begin(),symbol_pointer);
43+
return Builder.CreateCall(getOrAddPrintfFunc(context,module),*argV,"echo");
44+
}
45+
return NIL;
46+
}
47+
48+
EchoFunctionHandler::EchoFunctionHandler() = default;
49+
50+
int EchoFunctionHandler::getPriority() {
51+
return INTERNAL_IMPL;
52+
}
53+
54+
ExternFunctionHandler::ExternFunctionHandler() = default;
55+
56+
bool
57+
ExternFunctionHandler::externFunctionHandlerCompRule(ExternFunctionHandler *handler1, ExternFunctionHandler *handler2) {
58+
return handler1->getPriority() > handler2->getPriority();
59+
}
60+
61+
int ExternFunctionHandler::getPriority() {
62+
return MIN_IMPL;
63+
}
64+
65+
Value *SleepFunctionHandler::tryhandle(LLVMContext &context, Module &module, std::string callName,
66+
std::vector<Value *> *argV) {
67+
if (callName == "sleep") {
68+
return Builder.CreateCall(getOrAddSleepFunc(context,module),*argV);
69+
}
70+
return NIL;
71+
}
72+
73+
SleepFunctionHandler::SleepFunctionHandler() = default;
74+
75+
int SleepFunctionHandler::getPriority() {
76+
return INTERNAL_IMPL;
77+
}
78+
79+
Value *
80+
TimeFunctionHandler::tryhandle(LLVMContext &context, Module &module, std::string callName, std::vector<Value *> *argV) {
81+
if (callName == "now") {
82+
auto func = getOrAddTimeFunc(context,module);
83+
return Builder.CreateCall(func);
84+
}
85+
return NIL;
86+
}
87+
88+
TimeFunctionHandler::TimeFunctionHandler() = default;
89+
90+
int TimeFunctionHandler::getPriority() {
91+
return INTERNAL_IMPL;
92+
}
93+
94+
95+
96+
Function *ExternFunctionHandler::getExternFunc(LLVMContext &context, Module &module, const std::string &func_name,
97+
std::vector<Value *> *vector) {
98+
// 判断是否可用加
99+
if (func_name == "echo") {
100+
return ExternFunctionHandler::getOrAddPrintfFunc(context, module);
101+
} else if (func_name == "time") {
102+
return ExternFunctionHandler::getOrAddTimeFunc(context, module);
103+
} else if (func_name == "sleep") {
104+
return ExternFunctionHandler::getOrAddSleepFunc(context, module);
105+
}
106+
// 还未适配
107+
return NIL;
108+
}
109+
110+
Function *ExternFunctionHandler::getOrAddPrintfFunc(LLVMContext &context, Module &module) {
111+
auto funcs = module.functions();
112+
auto it = funcs.begin();
113+
for (; it != funcs.end(); it++) {
114+
if ((*it).getName() == "printf") {
115+
return &(*it);
116+
}
117+
}
118+
FunctionType *ty = FunctionType::get(Type::getInt32Ty(context), {Type::getInt8PtrTy(context)}, true);
119+
auto func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "printf", module);
120+
return func;
121+
}
122+
123+
Function *ExternFunctionHandler::getOrAddTimeFunc(LLVMContext &context, Module &module) {
124+
auto funcs = module.functions();
125+
auto it = funcs.begin();
126+
for (; it != funcs.end(); it++) {
127+
if ((*it).getName() == "__getms") {
128+
return &(*it);
129+
}
130+
}
131+
// std::vector<Type*> args;
132+
// args.push_back(Type::getInt64PtrTy(context));
133+
FunctionType *ty = FunctionType::get(Type::getInt64Ty(context), false);
134+
auto func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "__getms", module);
135+
return func;
136+
}
137+
138+
Function *ExternFunctionHandler::getOrAddSleepFunc(LLVMContext &context, Module &module) {
139+
auto funcs = module.functions();
140+
auto it = funcs.begin();
141+
for (; it != funcs.end(); it++) {
142+
if ((*it).getName() == "sleep") {
143+
return &(*it);
144+
}
145+
}
146+
// std::vector<Type*> args;
147+
// args.push_back(Type::getInt64PtrTy(context));
148+
FunctionType *ty = FunctionType::get(Type::getInt32Ty(context), Type::getInt32Ty(context), false);
149+
auto func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "sleep", module);
150+
return func;
151+
}

extern/ExternFunctionHandler.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// Created by 金韬 on 2021/3/4.
3+
//
4+
5+
#ifndef SYSYPLUS_COMPILER_EXTERNFUNCTIONHANDLER_H
6+
#define SYSYPLUS_COMPILER_EXTERNFUNCTIONHANDLER_H
7+
#include <cmath>
8+
9+
#include "Global.h"
10+
11+
#define INTERNAL_IMPL 10
12+
#define USER_IMPL 100
13+
14+
#define MIN_IMPL 0
15+
#define MAX_PRI 100
16+
17+
class ExternFunctionHandler {
18+
private:
19+
public:
20+
ExternFunctionHandler();
21+
22+
virtual Value* tryhandle(LLVMContext& context,
23+
Module& module,std::string callName,std::vector<Value*>* argV) = 0;
24+
25+
static bool externFunctionHandlerCompRule(ExternFunctionHandler* handler1,ExternFunctionHandler* handler2);
26+
27+
virtual int getPriority();
28+
29+
/**
30+
* 获取func
31+
* @param context
32+
* @param module
33+
* @param func_name
34+
* @param vector
35+
* @return
36+
*/
37+
static Function *getExternFunc(LLVMContext &context, Module &module, const std::string &func_name,
38+
std::vector<Value *>* vector);
39+
40+
static Function *getOrAddPrintfFunc(LLVMContext &context, Module &module);
41+
42+
static Function *getOrAddTimeFunc(LLVMContext &context, Module &module);
43+
44+
static Function *getOrAddSleepFunc(LLVMContext &context, Module &module);
45+
46+
};
47+
48+
49+
class EchoFunctionHandler : public ExternFunctionHandler {
50+
51+
public:
52+
EchoFunctionHandler();
53+
54+
Value* tryhandle(LLVMContext &context, Module &module, std::string callName, std::vector<Value *> *argV) override;
55+
56+
int getPriority() override;
57+
};
58+
59+
class TimeFunctionHandler : public ExternFunctionHandler {
60+
public:
61+
int getPriority() override;
62+
63+
TimeFunctionHandler();
64+
65+
Value* tryhandle(LLVMContext &context, Module &module, std::string callName, std::vector<Value *> *argV) override;
66+
};
67+
68+
class SleepFunctionHandler : public ExternFunctionHandler {
69+
public:
70+
int getPriority() override;
71+
72+
SleepFunctionHandler();
73+
74+
Value* tryhandle(LLVMContext &context, Module &module, std::string callName, std::vector<Value *> *argV) override;
75+
};
76+
77+
#endif //SYSYPLUS_COMPILER_EXTERNFUNCTIONHANDLER_H

extern/ExternFunctionLinker.cpp

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,22 @@
44

55
#include "ExternFunctionLinker.h"
66

7-
Function *ExternFunctionLinker::getExternFunc(LLVMContext& context,Module& module, const std::string &func_name) {
8-
// 判断是否可用加
9-
if (func_name == "echo"){
10-
return ExternFunctionLinker::getOrAddPrintfFunc(context,module);
11-
} else if (func_name == "time") {
12-
return ExternFunctionLinker::getOrAddTimeFunc(context, module);
13-
} else if (func_name == "sleep") {
14-
return ExternFunctionLinker::getOrAddSleepFunc(context, module);
15-
}
16-
// 还未适配
17-
return NIL;
18-
}
7+
std::vector<ExternFunctionHandler*> ExternFunctionLinker::handlers;
198

20-
Function* ExternFunctionLinker::getOrAddPrintfFunc(LLVMContext& context, Module &module) {
21-
auto funcs = module.functions();
22-
auto it = funcs.begin();
23-
for (; it != funcs.end(); it++) {
24-
if ((*it).getName() == "printf"){
25-
return &(*it);
9+
Value* ExternFunctionLinker::tryHandleFuncCall(LLVMContext &context, Module &module, const string &func_name,
10+
std::vector<Value *> *vector) {
11+
for (ExternFunctionHandler* handler : handlers) {
12+
auto v = handler->tryhandle(context,module,func_name,vector);
13+
if (v != NIL){
14+
return v;
2615
}
2716
}
28-
FunctionType* ty = FunctionType::get(Type::getInt32Ty(context),{Type::getInt8PtrTy(context)},true);
29-
auto func = Function::Create(ty,llvm::GlobalValue::ExternalLinkage,"printf",module);
30-
return func;
31-
}
32-
33-
Function *ExternFunctionLinker::getOrAddTimeFunc(LLVMContext &context, Module &module) {
34-
auto funcs = module.functions();
35-
auto it = funcs.begin();
36-
for (; it != funcs.end(); it++) {
37-
if ((*it).getName() == "__getms") {
38-
return &(*it);
39-
}
40-
}
41-
// std::vector<Type*> args;
42-
// args.push_back(Type::getInt64PtrTy(context));
43-
FunctionType *ty = FunctionType::get(Type::getInt64Ty(context), false);
44-
auto func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "__getms", module);
45-
return func;
17+
return NIL;
4618
}
4719

48-
Function *ExternFunctionLinker::getOrAddSleepFunc(LLVMContext &context, Module &module) {
49-
auto funcs = module.functions();
50-
auto it = funcs.begin();
51-
for (; it != funcs.end(); it++) {
52-
if ((*it).getName() == "sleep") {
53-
return &(*it);
54-
}
20+
void ExternFunctionLinker::registerHandler(ExternFunctionHandler *handler) {
21+
if (handler != NIL && std::find(handlers.begin(),handlers.end(),handler) == handlers.end()) {
22+
handlers.push_back(handler);
23+
sort(handlers.begin(),handlers.end(),ExternFunctionHandler::externFunctionHandlerCompRule);
5524
}
56-
// std::vector<Type*> args;
57-
// args.push_back(Type::getInt64PtrTy(context));
58-
FunctionType *ty = FunctionType::get(Type::getInt32Ty(context), Type::getInt32Ty(context), false);
59-
auto func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "sleep", module);
60-
return func;
6125
}

0 commit comments

Comments
 (0)