GCC Code Coverage Report


Directory: ../
File: src/irgenerator/StdFunctionManager.cpp
Date: 2025-02-05 01:09:36
Exec Total Coverage
Lines: 103 110 93.6%
Functions: 18 19 94.7%
Branches: 94 188 50.0%

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