GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 94.8% 128 / 0 / 135
Functions: 95.8% 23 / 0 / 24
Branches: 50.0% 118 / 0 / 236

src/irgenerator/StdFunctionManager.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "StdFunctionManager.h"
4
5 #include <SourceFile.h>
6 #include <driver/Driver.h>
7 #include <global/GlobalResourceManager.h>
8 #include <irgenerator/NameMangling.h>
9 #include <model/Function.h>
10
11 #include <llvm/IR/Module.h>
12
13 namespace spice::compiler {
14
15 2562 StdFunctionManager::StdFunctionManager(SourceFile *sourceFile, GlobalResourceManager &resourceManager, llvm::Module *module)
16
2/2
✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 4 taken 2558 times.
2562 : sourceFile(sourceFile), context(resourceManager.cliOptions.useLTO ? resourceManager.ltoContext : sourceFile->context),
17 2562 builder(sourceFile->builder), module(module) {}
18
19 6789 llvm::Function *StdFunctionManager::getPrintfFct() const {
20
3/6
✓ Branch 2 → 3 taken 6789 times.
✗ Branch 2 → 17 not taken.
✓ Branch 4 → 5 taken 6789 times.
✗ Branch 4 → 17 not taken.
✓ Branch 5 → 6 taken 6789 times.
✗ Branch 5 → 17 not taken.
6789 llvm::Function *printfFct = getFunction("printf", builder.getInt32Ty(), builder.getPtrTy(), true);
21 // Set attributes
22 6789 printfFct->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
23 6789 printfFct->addFnAttr(llvm::Attribute::NoFree);
24 6789 printfFct->addFnAttr(llvm::Attribute::NoUnwind);
25 6789 printfFct->addParamAttr(0, llvm::Attribute::getWithCaptureInfo(context, llvm::CaptureInfo::none()));
26 6789 printfFct->addParamAttr(0, llvm::Attribute::NoUndef);
27 6789 printfFct->addParamAttr(0, llvm::Attribute::ReadOnly);
28 6789 printfFct->addRetAttr(llvm::Attribute::NoUndef);
29 6789 return printfFct;
30 }
31
32 2498 llvm::Function *StdFunctionManager::getFPrintfFct() const {
33
4/8
✓ Branch 2 → 3 taken 2498 times.
✗ Branch 2 → 21 not taken.
✓ Branch 3 → 4 taken 2498 times.
✗ Branch 3 → 21 not taken.
✓ Branch 5 → 6 taken 2498 times.
✗ Branch 5 → 21 not taken.
✓ Branch 6 → 7 taken 2498 times.
✗ Branch 6 → 21 not taken.
2498 llvm::Function *fprintfFct = getFunction("fprintf", builder.getInt32Ty(), {builder.getPtrTy(), builder.getPtrTy()}, true);
34 // Set attributes
35 2498 fprintfFct->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
36 2498 fprintfFct->addFnAttr(llvm::Attribute::NoFree);
37 2498 fprintfFct->addParamAttr(0, llvm::Attribute::getWithCaptureInfo(context, llvm::CaptureInfo::none()));
38 2498 fprintfFct->addParamAttr(0, llvm::Attribute::NoUndef);
39 2498 fprintfFct->addParamAttr(1, llvm::Attribute::getWithCaptureInfo(context, llvm::CaptureInfo::none()));
40 2498 fprintfFct->addParamAttr(1, llvm::Attribute::NoUndef);
41 2498 fprintfFct->addParamAttr(1, llvm::Attribute::ReadOnly);
42 2498 fprintfFct->addRetAttr(llvm::Attribute::NoUndef);
43 2498 return fprintfFct;
44 }
45
46 8013 llvm::Function *StdFunctionManager::getExitFct() const {
47
2/4
✓ Branch 2 → 3 taken 8013 times.
✗ Branch 2 → 10 not taken.
✓ Branch 4 → 5 taken 8013 times.
✗ Branch 4 → 10 not taken.
8013 llvm::Function *exitFct = getProcedure("exit", builder.getInt32Ty());
48 // Set attributes
49 8013 exitFct->addFnAttr(llvm::Attribute::Cold);
50 8013 exitFct->addFnAttr(llvm::Attribute::NoReturn);
51 8013 exitFct->addFnAttr(llvm::Attribute::NoUnwind);
52 8013 return exitFct;
53 }
54
55 llvm::Function *StdFunctionManager::getFreeFct() const {
56 llvm::Function *freeFct = getProcedure("free", builder.getPtrTy());
57 // Set attributes
58 freeFct->addFnAttr(llvm::Attribute::NoUnwind);
59 freeFct->addParamAttr(0, llvm::Attribute::getWithCaptureInfo(context, llvm::CaptureInfo::none()));
60 freeFct->addParamAttr(0, llvm::Attribute::NoUndef);
61 freeFct->addParamAttr(0, llvm::Attribute::ReadOnly);
62 return freeFct;
63 }
64
65 296 llvm::Function *StdFunctionManager::getMemcmpFct() const {
66 296 llvm::Type *ptrTy = builder.getPtrTy();
67
3/6
✓ Branch 3 → 4 taken 296 times.
✗ Branch 3 → 10 not taken.
✓ Branch 5 → 6 taken 296 times.
✗ Branch 5 → 10 not taken.
✓ Branch 6 → 7 taken 296 times.
✗ Branch 6 → 10 not taken.
296 llvm::Function *memcmpFct = getFunction("memcmp", builder.getInt32Ty(), {ptrTy, ptrTy, builder.getInt64Ty()});
68 // Set attributes
69 296 memcmpFct->addFnAttr(llvm::Attribute::NoUnwind);
70 296 return memcmpFct;
71 }
72
73 2726 llvm::Function *StdFunctionManager::getMemcpyIntrinsic() const {
74 2726 llvm::Type *ptrTy = builder.getPtrTy();
75
3/6
✓ Branch 3 → 4 taken 2726 times.
✗ Branch 3 → 13 not taken.
✓ Branch 4 → 5 taken 2726 times.
✗ Branch 4 → 13 not taken.
✓ Branch 6 → 7 taken 2726 times.
✗ Branch 6 → 13 not taken.
2726 llvm::Function *memcpyFct = getProcedure("llvm.memcpy.p0.p0.i64", {ptrTy, ptrTy, builder.getInt64Ty(), builder.getInt1Ty()});
76 // Set attributes
77 2726 memcpyFct->addFnAttr(llvm::Attribute::NoCallback);
78 2726 memcpyFct->addFnAttr(llvm::Attribute::NoFree);
79 2726 memcpyFct->addFnAttr(llvm::Attribute::NoUnwind);
80 2726 memcpyFct->addFnAttr(llvm::Attribute::WillReturn);
81 2726 return memcpyFct;
82 }
83
84 78 llvm::Function *StdFunctionManager::getStringGetRawLengthStringFct() const {
85
2/4
✓ Branch 2 → 3 taken 78 times.
✗ Branch 2 → 34 not taken.
✓ Branch 5 → 6 taken 78 times.
✗ Branch 5 → 31 not taken.
156 const ParamList paramLst = {{QualType(TY_STRING), false}};
86
5/10
✓ Branch 8 → 9 taken 78 times.
✗ Branch 8 → 45 not taken.
✓ Branch 9 → 10 taken 78 times.
✗ Branch 9 → 42 not taken.
✓ Branch 10 → 11 taken 78 times.
✗ Branch 10 → 41 not taken.
✓ Branch 13 → 14 taken 78 times.
✗ Branch 13 → 37 not taken.
✓ Branch 14 → 15 taken 78 times.
✗ Branch 14 → 35 not taken.
234 const Function function("getRawLength", nullptr, QualType(TY_DYN), QualType(TY_LONG), paramLst, {}, nullptr);
87
1/2
✓ Branch 19 → 20 taken 78 times.
✗ Branch 19 → 53 not taken.
78 const std::string mangledName = NameMangling::mangleFunction(function);
88
3/6
✓ Branch 20 → 21 taken 78 times.
✗ Branch 20 → 49 not taken.
✓ Branch 22 → 23 taken 78 times.
✗ Branch 22 → 49 not taken.
✓ Branch 24 → 25 taken 78 times.
✗ Branch 24 → 49 not taken.
156 return getFunction(mangledName.c_str(), builder.getInt64Ty(), {builder.getPtrTy()});
89 78 }
90
91 423 llvm::Function *StdFunctionManager::getStringIsRawEqualStringStringFct() const {
92
3/6
✓ Branch 2 → 3 taken 423 times.
✗ Branch 2 → 36 not taken.
✓ Branch 3 → 4 taken 423 times.
✗ Branch 3 → 36 not taken.
✓ Branch 6 → 7 taken 423 times.
✗ Branch 6 → 33 not taken.
846 const ParamList paramLst = {{QualType(TY_STRING), false}, {QualType(TY_STRING), false}};
93
5/10
✓ Branch 9 → 10 taken 423 times.
✗ Branch 9 → 47 not taken.
✓ Branch 10 → 11 taken 423 times.
✗ Branch 10 → 44 not taken.
✓ Branch 11 → 12 taken 423 times.
✗ Branch 11 → 43 not taken.
✓ Branch 14 → 15 taken 423 times.
✗ Branch 14 → 39 not taken.
✓ Branch 15 → 16 taken 423 times.
✗ Branch 15 → 37 not taken.
1269 const Function function("isRawEqual", nullptr, QualType(TY_DYN), QualType(TY_BOOL), paramLst, {}, nullptr);
94
1/2
✓ Branch 20 → 21 taken 423 times.
✗ Branch 20 → 55 not taken.
423 const std::string mangledName = NameMangling::mangleFunction(function);
95
4/8
✓ Branch 21 → 22 taken 423 times.
✗ Branch 21 → 51 not taken.
✓ Branch 22 → 23 taken 423 times.
✗ Branch 22 → 51 not taken.
✓ Branch 24 → 25 taken 423 times.
✗ Branch 24 → 51 not taken.
✓ Branch 26 → 27 taken 423 times.
✗ Branch 26 → 51 not taken.
846 return getFunction(mangledName.c_str(), builder.getInt1Ty(), {builder.getPtrTy(), builder.getPtrTy()});
96 423 }
97
98 246 llvm::Function *StdFunctionManager::getAllocUnsafeLongFct() const {
99
1/2
✓ Branch 2 → 3 taken 246 times.
✗ Branch 2 → 60 not taken.
246 QualType unsignedLong(TY_LONG);
100
1/2
✓ Branch 3 → 4 taken 246 times.
✗ Branch 3 → 60 not taken.
246 unsignedLong.makeUnsigned();
101
1/2
✓ Branch 6 → 7 taken 246 times.
✗ Branch 6 → 33 not taken.
492 const ParamList paramLst = {{unsignedLong, false}};
102
6/12
✓ Branch 9 → 10 taken 246 times.
✗ Branch 9 → 48 not taken.
✓ Branch 10 → 11 taken 246 times.
✗ Branch 10 → 44 not taken.
✓ Branch 11 → 12 taken 246 times.
✗ Branch 11 → 44 not taken.
✓ Branch 12 → 13 taken 246 times.
✗ Branch 12 → 43 not taken.
✓ Branch 15 → 16 taken 246 times.
✗ Branch 15 → 39 not taken.
✓ Branch 16 → 17 taken 246 times.
✗ Branch 16 → 37 not taken.
738 const Function function("sAllocUnsafe", nullptr, QualType(TY_DYN), QualType(TY_BYTE).toPtr(nullptr), paramLst, {}, nullptr);
103
1/2
✓ Branch 21 → 22 taken 246 times.
✗ Branch 21 → 56 not taken.
246 const std::string mangledName = NameMangling::mangleFunction(function);
104
3/6
✓ Branch 22 → 23 taken 246 times.
✗ Branch 22 → 52 not taken.
✓ Branch 24 → 25 taken 246 times.
✗ Branch 24 → 52 not taken.
✓ Branch 26 → 27 taken 246 times.
✗ Branch 26 → 52 not taken.
492 return getFunction(mangledName.c_str(), builder.getPtrTy(), {builder.getInt64Ty()});
105 246 }
106
107 350 llvm::Function *StdFunctionManager::getDeallocBytePtrRefFct() const {
108
2/4
✓ Branch 2 → 3 taken 350 times.
✗ Branch 2 → 33 not taken.
✓ Branch 3 → 4 taken 350 times.
✗ Branch 3 → 33 not taken.
350 QualType heapBytePtrType = QualType(TY_BYTE).toPtr(nullptr);
109
1/2
✓ Branch 4 → 5 taken 350 times.
✗ Branch 4 → 60 not taken.
350 heapBytePtrType.makeHeap();
110
2/4
✓ Branch 5 → 6 taken 350 times.
✗ Branch 5 → 37 not taken.
✓ Branch 8 → 9 taken 350 times.
✗ Branch 8 → 34 not taken.
700 const ParamList paramLst = {{heapBytePtrType.toRef(nullptr), false}};
111
5/10
✓ Branch 11 → 12 taken 350 times.
✗ Branch 11 → 48 not taken.
✓ Branch 12 → 13 taken 350 times.
✗ Branch 12 → 45 not taken.
✓ Branch 13 → 14 taken 350 times.
✗ Branch 13 → 44 not taken.
✓ Branch 16 → 17 taken 350 times.
✗ Branch 16 → 40 not taken.
✓ Branch 17 → 18 taken 350 times.
✗ Branch 17 → 38 not taken.
1050 const Function function("sDealloc", nullptr, QualType(TY_DYN), QualType(TY_DYN), paramLst, {}, nullptr);
112
1/2
✓ Branch 22 → 23 taken 350 times.
✗ Branch 22 → 56 not taken.
350 const std::string mangledName = NameMangling::mangleFunction(function);
113
2/4
✓ Branch 23 → 24 taken 350 times.
✗ Branch 23 → 52 not taken.
✓ Branch 26 → 27 taken 350 times.
✗ Branch 26 → 52 not taken.
700 return getProcedure(mangledName.c_str(), {builder.getPtrTy()});
114 350 }
115
116 18 llvm::Function *StdFunctionManager::getIterateFct(const Function *spiceFunc) const {
117
1/2
✓ Branch 2 → 3 taken 18 times.
✗ Branch 2 → 17 not taken.
18 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
118
1/2
✓ Branch 3 → 4 taken 18 times.
✗ Branch 3 → 15 not taken.
18 llvm::Type *iteratorType = spiceFunc->returnType.toLLVMType(sourceFile);
119
3/6
✓ Branch 4 → 5 taken 18 times.
✗ Branch 4 → 13 not taken.
✓ Branch 5 → 6 taken 18 times.
✗ Branch 5 → 13 not taken.
✓ Branch 8 → 9 taken 18 times.
✗ Branch 8 → 13 not taken.
36 return getFunction(functionName.c_str(), iteratorType, {builder.getPtrTy(), builder.getInt64Ty()});
120 18 }
121
122 432 llvm::Function *StdFunctionManager::getIteratorFct(const Function *spiceFunc) const {
123
1/2
✓ Branch 2 → 3 taken 432 times.
✗ Branch 2 → 16 not taken.
432 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
124
1/2
✓ Branch 3 → 4 taken 432 times.
✗ Branch 3 → 14 not taken.
432 llvm::Type *iteratorType = spiceFunc->returnType.toLLVMType(sourceFile);
125
2/4
✓ Branch 4 → 5 taken 432 times.
✗ Branch 4 → 12 not taken.
✓ Branch 7 → 8 taken 432 times.
✗ Branch 7 → 12 not taken.
864 return getFunction(functionName.c_str(), iteratorType, builder.getPtrTy());
126 432 }
127
128 366 llvm::Function *StdFunctionManager::getIteratorGetFct(const Function *spiceFunc) const {
129
1/2
✓ Branch 2 → 3 taken 366 times.
✗ Branch 2 → 16 not taken.
366 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
130
3/6
✓ Branch 3 → 4 taken 366 times.
✗ Branch 3 → 12 not taken.
✓ Branch 5 → 6 taken 366 times.
✗ Branch 5 → 12 not taken.
✓ Branch 7 → 8 taken 366 times.
✗ Branch 7 → 12 not taken.
732 return getFunction(functionName.c_str(), builder.getPtrTy(), builder.getPtrTy());
131 366 }
132
133 117 llvm::Function *StdFunctionManager::getIteratorGetIdxFct(const Function *spiceFunc) const {
134
1/2
✓ Branch 2 → 3 taken 117 times.
✗ Branch 2 → 16 not taken.
117 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
135
1/2
✓ Branch 3 → 4 taken 117 times.
✗ Branch 3 → 14 not taken.
117 llvm::Type *pairTy = spiceFunc->returnType.toLLVMType(sourceFile);
136
2/4
✓ Branch 4 → 5 taken 117 times.
✗ Branch 4 → 12 not taken.
✓ Branch 7 → 8 taken 117 times.
✗ Branch 7 → 12 not taken.
234 return getFunction(functionName.c_str(), pairTy, builder.getPtrTy());
137 117 }
138
139 483 llvm::Function *StdFunctionManager::getIteratorIsValidFct(const Function *spiceFunc) const {
140
1/2
✓ Branch 2 → 3 taken 483 times.
✗ Branch 2 → 16 not taken.
483 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
141
3/6
✓ Branch 3 → 4 taken 483 times.
✗ Branch 3 → 12 not taken.
✓ Branch 5 → 6 taken 483 times.
✗ Branch 5 → 12 not taken.
✓ Branch 7 → 8 taken 483 times.
✗ Branch 7 → 12 not taken.
966 return getFunction(functionName.c_str(), builder.getInt1Ty(), builder.getPtrTy());
142 483 }
143
144 483 llvm::Function *StdFunctionManager::getIteratorNextFct(const Function *spiceFunc) const {
145
1/2
✓ Branch 2 → 3 taken 483 times.
✗ Branch 2 → 15 not taken.
483 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
146
2/4
✓ Branch 3 → 4 taken 483 times.
✗ Branch 3 → 11 not taken.
✓ Branch 6 → 7 taken 483 times.
✗ Branch 6 → 11 not taken.
966 return getProcedure(functionName.c_str(), builder.getPtrTy());
147 483 }
148
149 56 llvm::Function *StdFunctionManager::getResultIsErrFct(const Function *spiceFunc) const {
150
1/2
✓ Branch 2 → 3 taken 56 times.
✗ Branch 2 → 16 not taken.
56 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
151
3/6
✓ Branch 3 → 4 taken 56 times.
✗ Branch 3 → 12 not taken.
✓ Branch 5 → 6 taken 56 times.
✗ Branch 5 → 12 not taken.
✓ Branch 7 → 8 taken 56 times.
✗ Branch 7 → 12 not taken.
112 return getFunction(functionName.c_str(), builder.getInt1Ty(), builder.getPtrTy());
152 56 }
153
154 56 llvm::Function *StdFunctionManager::getResultUnwrapFct(const Function *spiceFunc) const {
155
1/2
✓ Branch 2 → 3 taken 56 times.
✗ Branch 2 → 16 not taken.
56 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
156
3/6
✓ Branch 3 → 4 taken 56 times.
✗ Branch 3 → 12 not taken.
✓ Branch 5 → 6 taken 56 times.
✗ Branch 5 → 12 not taken.
✓ Branch 7 → 8 taken 56 times.
✗ Branch 7 → 12 not taken.
112 return getFunction(functionName.c_str(), builder.getPtrTy(), builder.getPtrTy());
157 56 }
158
159 56 llvm::Function *StdFunctionManager::getResultGetErrFct(const Function *spiceFunc) const {
160
1/2
✓ Branch 2 → 3 taken 56 times.
✗ Branch 2 → 16 not taken.
56 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
161
3/6
✓ Branch 3 → 4 taken 56 times.
✗ Branch 3 → 12 not taken.
✓ Branch 5 → 6 taken 56 times.
✗ Branch 5 → 12 not taken.
✓ Branch 7 → 8 taken 56 times.
✗ Branch 7 → 12 not taken.
112 return getFunction(functionName.c_str(), builder.getPtrTy(), builder.getPtrTy());
162 56 }
163
164 56 llvm::Function *StdFunctionManager::getResultErrCtorFct(const Function *spiceFunc) const {
165
1/2
✓ Branch 2 → 3 taken 56 times.
✗ Branch 2 → 16 not taken.
56 const std::string functionName = NameMangling::mangleFunction(*spiceFunc);
166
1/2
✓ Branch 3 → 4 taken 56 times.
✗ Branch 3 → 14 not taken.
56 llvm::Type *resultType = spiceFunc->returnType.toLLVMType(sourceFile);
167
2/4
✓ Branch 4 → 5 taken 56 times.
✗ Branch 4 → 12 not taken.
✓ Branch 7 → 8 taken 56 times.
✗ Branch 7 → 12 not taken.
112 return getFunction(functionName.c_str(), resultType, builder.getPtrTy());
168 56 }
169
170 11 llvm::Function *StdFunctionManager::getAcrtIOFuncFct() const {
171
3/6
✓ Branch 2 → 3 taken 11 times.
✗ Branch 2 → 9 not taken.
✓ Branch 4 → 5 taken 11 times.
✗ Branch 4 → 9 not taken.
✓ Branch 5 → 6 taken 11 times.
✗ Branch 5 → 9 not taken.
11 llvm::Function *stdErrPFct = getFunction("__acrt_iob_func", builder.getPtrTy(), builder.getInt32Ty());
172 11 stdErrPFct->setDSOLocal(true);
173 11 return stdErrPFct;
174 }
175
176 23553 llvm::Function *StdFunctionManager::getFunction(const char *funcName, llvm::Type *returnType, llvm::ArrayRef<llvm::Type *> args,
177 bool varArg /*=false*/) const {
178 // Check if function already exists in the current module
179
2/4
✓ Branch 2 → 3 taken 23553 times.
✗ Branch 2 → 14 not taken.
✓ Branch 3 → 4 taken 23553 times.
✗ Branch 3 → 14 not taken.
23553 llvm::Function *opFct = module->getFunction(funcName);
180
2/2
✓ Branch 4 → 5 taken 19091 times.
✓ Branch 4 → 6 taken 4462 times.
23553 if (opFct != nullptr)
181 19091 return opFct;
182
183 // Add function to the current module
184 4462 llvm::FunctionType *opFctTy = llvm::FunctionType::get(returnType, args, varArg);
185
2/4
✓ Branch 7 → 8 taken 4462 times.
✗ Branch 7 → 15 not taken.
✓ Branch 8 → 9 taken 4462 times.
✗ Branch 8 → 15 not taken.
4462 module->getOrInsertFunction(funcName, opFctTy);
186
2/4
✓ Branch 9 → 10 taken 4462 times.
✗ Branch 9 → 16 not taken.
✓ Branch 10 → 11 taken 4462 times.
✗ Branch 10 → 16 not taken.
4462 return module->getFunction(funcName);
187 }
188
189 11572 llvm::Function *StdFunctionManager::getProcedure(const char *procName, llvm::ArrayRef<llvm::Type *> args) const {
190 11572 return getFunction(procName, builder.getVoidTy(), args, false);
191 }
192
193 } // namespace spice::compiler
194