GCC Code Coverage Report


Directory: ../
File: src/irgenerator/StdFunctionManager.cpp
Date: 2024-12-24 01:17:15
Exec Total Coverage
Lines: 93 100 93.0%
Functions: 17 18 94.4%
Branches: 90 180 50.0%

Line Branch Exec Source
1 // Copyright (c) 2021-2024 ChilliBits. All rights reserved.
2
3 #include "StdFunctionManager.h"
4
5 #include <llvm/IR/Module.h>
6
7 #include <SourceFile.h>
8 #include <global/GlobalResourceManager.h>
9 #include <irgenerator/NameMangling.h>
10 #include <model/Function.h>
11
12 namespace spice::compiler {
13
14 678 StdFunctionManager::StdFunctionManager(SourceFile *sourceFile, GlobalResourceManager &resourceManager, llvm::Module *module)
15
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 676 times.
678 : sourceFile(sourceFile), context(resourceManager.cliOptions.useLTO ? resourceManager.ltoContext : sourceFile->context),
16 678 builder(sourceFile->builder), module(module) {}
17
18 1582 llvm::Function *StdFunctionManager::getPrintfFct() const {
19
3/6
✓ Branch 1 taken 1582 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1582 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1582 times.
✗ Branch 9 not taken.
1582 llvm::Function *printfFct = getFunction("printf", builder.getInt32Ty(), builder.getPtrTy(), true);
20 // Set attributes
21 1582 printfFct->addFnAttr(llvm::Attribute::NoFree);
22 1582 printfFct->addFnAttr(llvm::Attribute::NoUnwind);
23 1582 printfFct->addParamAttr(0, llvm::Attribute::NoCapture);
24 1582 printfFct->addParamAttr(0, llvm::Attribute::NoUndef);
25 1582 printfFct->addParamAttr(0, llvm::Attribute::ReadOnly);
26 1582 printfFct->addRetAttr(llvm::Attribute::NoUndef);
27 1582 return printfFct;
28 }
29
30 1001 llvm::Function *StdFunctionManager::getExitFct() const {
31
2/4
✓ Branch 1 taken 1001 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1001 times.
✗ Branch 6 not taken.
1001 llvm::Function *exitFct = getProcedure("exit", builder.getInt32Ty());
32 // Set attributes
33 1001 exitFct->addFnAttr(llvm::Attribute::Cold);
34 1001 exitFct->addFnAttr(llvm::Attribute::NoReturn);
35 1001 exitFct->addFnAttr(llvm::Attribute::NoUnwind);
36 1001 return exitFct;
37 }
38
39 llvm::Function *StdFunctionManager::getFreeFct() const {
40 llvm::Function *freeFct = getProcedure("free", builder.getPtrTy());
41 // Set attributes
42 freeFct->addFnAttr(llvm::Attribute::NoUnwind);
43 freeFct->addParamAttr(0, llvm::Attribute::NoCapture);
44 freeFct->addParamAttr(0, llvm::Attribute::NoUndef);
45 freeFct->addParamAttr(0, llvm::Attribute::ReadOnly);
46 return freeFct;
47 }
48
49 20 llvm::Function *StdFunctionManager::getMemcmpFct() const {
50 20 llvm::Type *ptrTy = builder.getPtrTy();
51
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
20 llvm::Function *memcmpFct = getFunction("memcmp", builder.getInt32Ty(), {ptrTy, ptrTy, builder.getInt64Ty()});
52 // Set attributes
53 20 memcmpFct->addFnAttr(llvm::Attribute::NoUnwind);
54 20 return memcmpFct;
55 }
56
57 155 llvm::Function *StdFunctionManager::getMemcpyIntrinsic() const {
58 155 llvm::Type *ptrTy = builder.getPtrTy();
59
3/6
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 155 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 155 times.
✗ Branch 9 not taken.
155 llvm::Function *memcpyFct = getProcedure("llvm.memcpy.p0.p0.i64", {ptrTy, ptrTy, builder.getInt64Ty(), builder.getInt1Ty()});
60 // Set attributes
61 155 memcpyFct->addFnAttr(llvm::Attribute::NoCallback);
62 155 memcpyFct->addFnAttr(llvm::Attribute::NoFree);
63 155 memcpyFct->addFnAttr(llvm::Attribute::NoUnwind);
64 155 memcpyFct->addFnAttr(llvm::Attribute::WillReturn);
65 155 return memcpyFct;
66 }
67
68 23 llvm::Function *StdFunctionManager::getStringGetRawLengthStringFct() const {
69
2/4
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
46 const ParamList paramLst = {{QualType(TY_STRING), false}};
70
4/8
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 23 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 23 times.
✗ Branch 12 not taken.
69 const Function function("getRawLength", nullptr, QualType(TY_DYN), QualType(TY_LONG), paramLst, {}, nullptr);
71
1/2
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
23 const std::string mangledName = NameMangling::mangleFunction(function);
72
3/6
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 23 times.
✗ Branch 10 not taken.
46 return getFunction(mangledName.c_str(), builder.getInt64Ty(), {builder.getPtrTy()});
73 23 }
74
75 121 llvm::Function *StdFunctionManager::getStringIsRawEqualStringStringFct() const {
76
3/6
✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 121 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 121 times.
✗ Branch 8 not taken.
242 const ParamList paramLst = {{QualType(TY_STRING), false}, {QualType(TY_STRING), false}};
77
4/8
✓ Branch 2 taken 121 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 121 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 121 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 121 times.
✗ Branch 12 not taken.
363 const Function function("isRawEqual", nullptr, QualType(TY_DYN), QualType(TY_BOOL), paramLst, {}, nullptr);
78
1/2
✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
121 const std::string mangledName = NameMangling::mangleFunction(function);
79
4/8
✓ Branch 1 taken 121 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 121 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 121 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 121 times.
✗ Branch 13 not taken.
242 return getFunction(mangledName.c_str(), builder.getInt1Ty(), {builder.getPtrTy(), builder.getPtrTy()});
80 121 }
81
82 4 llvm::Function *StdFunctionManager::getAllocUnsafeLongFct() const {
83
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 QualType unsignedLong(TY_LONG);
84
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 unsignedLong.makeUnsigned();
85
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 const ParamList paramLst = {{unsignedLong, false}};
86
5/10
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
12 const Function function("sAllocUnsafe", nullptr, QualType(TY_DYN), QualType(TY_BYTE).toPtr(nullptr), paramLst, {}, nullptr);
87
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 const std::string mangledName = NameMangling::mangleFunction(function);
88
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
8 return getFunction(mangledName.c_str(), builder.getPtrTy(), {builder.getInt64Ty()});
89 4 }
90
91 53 llvm::Function *StdFunctionManager::getDeallocBytePtrRefFct() const {
92
4/8
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 53 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 53 times.
✗ Branch 11 not taken.
106 const ParamList paramLst = {{QualType(TY_BYTE).toPtr(nullptr).toRef(nullptr), false}};
93
4/8
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 53 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 53 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 53 times.
✗ Branch 12 not taken.
159 const Function function("sDealloc", nullptr, QualType(TY_DYN), QualType(TY_DYN), paramLst, {}, nullptr);
94
1/2
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
53 const std::string mangledName = NameMangling::mangleFunction(function);
95
2/4
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 53 times.
✗ Branch 7 not taken.
106 return getProcedure(mangledName.c_str(), {builder.getPtrTy()});
96 53 }
97
98 7 llvm::Function *StdFunctionManager::getIterateFct(const Function *spiceFunc) const {
99
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
100
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 llvm::Type *iteratorType = spiceFunc->returnType.toLLVMType(sourceFile);
101
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 7 times.
✗ Branch 10 not taken.
14 return getFunction(functionName.c_str(), iteratorType, {builder.getPtrTy(), builder.getInt64Ty()});
102 7 }
103
104 63 llvm::Function *StdFunctionManager::getIteratorFct(const Function *spiceFunc) const {
105
1/2
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
63 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
106
1/2
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
63 llvm::Type *iteratorType = spiceFunc->returnType.toLLVMType(sourceFile);
107
2/4
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 63 times.
✗ Branch 7 not taken.
126 return getFunction(functionName.c_str(), iteratorType, builder.getPtrTy());
108 63 }
109
110 80 llvm::Function *StdFunctionManager::getIteratorGetFct(const Function *spiceFunc) const {
111
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
112
3/6
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 80 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 80 times.
✗ Branch 10 not taken.
160 return getFunction(functionName.c_str(), builder.getPtrTy(), builder.getPtrTy());
113 80 }
114
115 5 llvm::Function *StdFunctionManager::getIteratorGetIdxFct(const Function *spiceFunc) const {
116
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
117
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 llvm::Type *pairTy = spiceFunc->returnType.toLLVMType(sourceFile);
118
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
10 return getFunction(functionName.c_str(), pairTy, builder.getPtrTy());
119 5 }
120
121 85 llvm::Function *StdFunctionManager::getIteratorIsValidFct(const Function *spiceFunc) const {
122
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
123
3/6
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 85 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 85 times.
✗ Branch 10 not taken.
170 return getFunction(functionName.c_str(), builder.getInt1Ty(), builder.getPtrTy());
124 85 }
125
126 85 llvm::Function *StdFunctionManager::getIteratorNextFct(const Function *spiceFunc) const {
127
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
128
2/4
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 85 times.
✗ Branch 7 not taken.
170 return getProcedure(functionName.c_str(), builder.getPtrTy());
129 85 }
130
131 3284 llvm::Function *StdFunctionManager::getFunction(const char *funcName, llvm::Type *returnType, llvm::ArrayRef<llvm::Type *> args,
132 bool varArg /*=false*/) const {
133 // Check if function already exists in the current module
134
2/4
✓ Branch 1 taken 3284 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3284 times.
✗ Branch 5 not taken.
3284 llvm::Function *opFct = module->getFunction(funcName);
135
2/2
✓ Branch 0 taken 2206 times.
✓ Branch 1 taken 1078 times.
3284 if (opFct != nullptr)
136 2206 return opFct;
137
138 // Add function to the current module
139 1078 llvm::FunctionType *opFctTy = llvm::FunctionType::get(returnType, args, varArg);
140
2/4
✓ Branch 1 taken 1078 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1078 times.
✗ Branch 5 not taken.
1078 module->getOrInsertFunction(funcName, opFctTy);
141
2/4
✓ Branch 1 taken 1078 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1078 times.
✗ Branch 5 not taken.
1078 return module->getFunction(funcName);
142 }
143
144 1294 llvm::Function *StdFunctionManager::getProcedure(const char *procName, llvm::ArrayRef<llvm::Type *> args) const {
145 1294 return getFunction(procName, builder.getVoidTy(), args, false);
146 }
147
148 } // namespace spice::compiler
149