Skip to content

Commit bd0d45e

Browse files
committed
LLVMTypeAnalyzer: Add pointer const qualifiers
1 parent ae4690a commit bd0d45e

File tree

2 files changed

+99
-81
lines changed

2 files changed

+99
-81
lines changed

src/engine/internal/llvm/llvmtypeanalyzer.cpp

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,40 @@ static const std::unordered_set<LLVMInstruction::Type>
1010

1111
static const std::unordered_set<LLVMInstruction::Type> LIST_WRITE_INSTRUCTIONS = { LLVMInstruction::Type::AppendToList, LLVMInstruction::Type::InsertToList, LLVMInstruction::Type::ListReplace };
1212

13-
Compiler::StaticType LLVMTypeAnalyzer::variableType(Variable *var, LLVMInstruction *pos, Compiler::StaticType previousType) const
13+
Compiler::StaticType LLVMTypeAnalyzer::variableType(const Variable *var, const LLVMInstruction *pos, Compiler::StaticType previousType) const
1414
{
1515
InstructionSet visitedInstructions;
16-
std::unordered_map<List *, Compiler::StaticType> listTypes;
16+
std::unordered_map<const List *, Compiler::StaticType> listTypes;
1717
return variableType(var, pos, previousType, listTypes, visitedInstructions);
1818
}
1919

20-
Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranch(Variable *var, LLVMInstruction *start, Compiler::StaticType previousType) const
20+
Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranch(const Variable *var, const LLVMInstruction *start, Compiler::StaticType previousType) const
2121
{
2222
InstructionSet visitedInstructions;
2323
return variableTypeAfterBranch(var, start, previousType, visitedInstructions);
2424
}
2525

26-
Compiler::StaticType LLVMTypeAnalyzer::listType(List *list, LLVMInstruction *pos, Compiler::StaticType previousType, bool isEmpty) const
26+
Compiler::StaticType LLVMTypeAnalyzer::listType(const List *list, const LLVMInstruction *pos, Compiler::StaticType previousType, bool isEmpty) const
2727
{
2828
InstructionSet visitedInstructions;
29-
std::unordered_map<List *, Compiler::StaticType> listTypes;
29+
std::unordered_map<const List *, Compiler::StaticType> listTypes;
3030
return listType(list, pos, previousType, isEmpty, listTypes, visitedInstructions);
3131
}
3232

33-
Compiler::StaticType LLVMTypeAnalyzer::listTypeAfterBranch(List *list, LLVMInstruction *start, Compiler::StaticType previousType, bool isEmpty) const
33+
Compiler::StaticType LLVMTypeAnalyzer::listTypeAfterBranch(const List *list, const LLVMInstruction *start, Compiler::StaticType previousType, bool isEmpty) const
3434
{
3535
bool write = false; // only used internally (the compiler doesn't need this)
3636
InstructionSet visitedInstructions;
37-
std::unordered_map<List *, Compiler::StaticType> listTypes;
37+
std::unordered_map<const List *, Compiler::StaticType> listTypes;
3838
return listTypeAfterBranch(list, start, previousType, isEmpty, nullptr, write, listTypes, visitedInstructions);
3939
}
4040

41-
Compiler::StaticType
42-
LLVMTypeAnalyzer::variableType(Variable *var, LLVMInstruction *pos, Compiler::StaticType previousType, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions)
43-
const
41+
Compiler::StaticType LLVMTypeAnalyzer::variableType(
42+
const Variable *var,
43+
const LLVMInstruction *pos,
44+
Compiler::StaticType previousType,
45+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
46+
InstructionSet &visitedInstructions) const
4447
{
4548
if (!var || !pos)
4649
return Compiler::StaticType::Unknown;
@@ -63,11 +66,11 @@ LLVMTypeAnalyzer::variableType(Variable *var, LLVMInstruction *pos, Compiler::St
6366
visitedInstructions.insert(pos);
6467

6568
// Check the last write operation before the instruction
66-
LLVMInstruction *ins = pos;
67-
LLVMInstruction *write = nullptr;
68-
std::pair<LLVMInstruction *, int> firstBranch = { nullptr, 0 };
69-
std::pair<LLVMInstruction *, int> firstElseBranch = { nullptr, 0 };
70-
LLVMInstruction *ourBranch = nullptr;
69+
const LLVMInstruction *ins = pos;
70+
const LLVMInstruction *write = nullptr;
71+
std::pair<const LLVMInstruction *, int> firstBranch = { nullptr, 0 };
72+
std::pair<const LLVMInstruction *, int> firstElseBranch = { nullptr, 0 };
73+
const LLVMInstruction *ourBranch = nullptr;
7174
int level = 0;
7275

7376
while (ins) {
@@ -126,32 +129,32 @@ LLVMTypeAnalyzer::variableType(Variable *var, LLVMInstruction *pos, Compiler::St
126129
return previousType;
127130
}
128131

129-
Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranch(Variable *var, LLVMInstruction *start, Compiler::StaticType previousType, InstructionSet &visitedInstructions) const
132+
Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranch(const Variable *var, const LLVMInstruction *start, Compiler::StaticType previousType, InstructionSet &visitedInstructions) const
130133
{
131134
if (!var || !start)
132135
return previousType;
133136

134-
LLVMInstruction *end = branchEnd(start);
137+
const LLVMInstruction *end = branchEnd(start);
135138

136139
if (!end)
137140
return Compiler::StaticType::Unknown;
138141

139142
// Process the branch from end
140143
bool write = false; // only used internally (the compiler doesn't need this)
141-
std::unordered_map<List *, Compiler::StaticType> listTypes;
144+
std::unordered_map<const List *, Compiler::StaticType> listTypes;
142145
return variableTypeAfterBranchFromEnd(var, end, previousType, write, listTypes, visitedInstructions);
143146
}
144147

145148
Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranchFromEnd(
146-
Variable *var,
147-
LLVMInstruction *end,
149+
const Variable *var,
150+
const LLVMInstruction *end,
148151
Compiler::StaticType previousType,
149152
bool &write,
150-
std::unordered_map<List *, Compiler::StaticType> listTypes,
153+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
151154
InstructionSet &visitedInstructions) const
152155
{
153156
// Find the last write instruction
154-
LLVMInstruction *ins = end->previous;
157+
const LLVMInstruction *ins = end->previous;
155158
bool typeMightReset = false;
156159

157160
while (ins && !isLoopStart(ins) && !isIfStart(ins)) {
@@ -201,8 +204,13 @@ Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranchFromEnd(
201204
return previousType;
202205
}
203206

204-
Compiler::StaticType LLVMTypeAnalyzer::
205-
listType(List *list, LLVMInstruction *pos, Compiler::StaticType previousType, bool isEmpty, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const
207+
Compiler::StaticType LLVMTypeAnalyzer::listType(
208+
const List *list,
209+
const LLVMInstruction *pos,
210+
Compiler::StaticType previousType,
211+
bool isEmpty,
212+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
213+
InstructionSet &visitedInstructions) const
206214
{
207215
if (!list || !pos)
208216
return Compiler::StaticType::Unknown;
@@ -223,10 +231,10 @@ Compiler::StaticType LLVMTypeAnalyzer::
223231
visitedInstructions.insert(pos);
224232
listTypes[list] = previousType;
225233

226-
LLVMInstruction *ins = pos;
227-
LLVMInstruction *previous = nullptr;
228-
std::pair<LLVMInstruction *, int> firstBranch = { nullptr, 0 };
229-
std::pair<LLVMInstruction *, int> lastClear = { nullptr, 0 };
234+
const LLVMInstruction *ins = pos;
235+
const LLVMInstruction *previous = nullptr;
236+
std::pair<const LLVMInstruction *, int> firstBranch = { nullptr, 0 };
237+
std::pair<const LLVMInstruction *, int> lastClear = { nullptr, 0 };
230238
int level = 0;
231239

232240
// Find a start instruction (list clear in the top level or the first instruction)
@@ -305,13 +313,13 @@ Compiler::StaticType LLVMTypeAnalyzer::
305313
}
306314

307315
Compiler::StaticType LLVMTypeAnalyzer::listTypeAfterBranch(
308-
List *list,
309-
LLVMInstruction *start,
316+
const List *list,
317+
const LLVMInstruction *start,
310318
Compiler::StaticType previousType,
311319
bool isEmpty,
312-
LLVMInstruction *query,
320+
const LLVMInstruction *query,
313321
bool &write,
314-
std::unordered_map<List *, Compiler::StaticType> listTypes,
322+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
315323
InstructionSet &visitedInstructions) const
316324
{
317325
write = false;
@@ -323,7 +331,7 @@ Compiler::StaticType LLVMTypeAnalyzer::listTypeAfterBranch(
323331

324332
bool isLoop = isLoopStart(start);
325333
bool clearBeforeQueryPoint = false;
326-
LLVMInstruction *ins = start->next;
334+
const LLVMInstruction *ins = start->next;
327335

328336
while (ins && !(isLoopEnd(ins) || isIfEnd(ins) || isElse(ins))) {
329337
if (isLoopStart(ins) || isIfStart(ins)) {
@@ -385,7 +393,7 @@ bool LLVMTypeAnalyzer::handleListWrite(Compiler::StaticType writeType, Compiler:
385393
return true;
386394
}
387395

388-
LLVMInstruction *LLVMTypeAnalyzer::branchEnd(LLVMInstruction *start) const
396+
const LLVMInstruction *LLVMTypeAnalyzer::branchEnd(const LLVMInstruction *start) const
389397
{
390398
assert(start);
391399
assert(isLoopStart(start) || isIfStart(start) || isElse(start));
@@ -409,7 +417,7 @@ LLVMInstruction *LLVMTypeAnalyzer::branchEnd(LLVMInstruction *start) const
409417
return ins;
410418
}
411419

412-
LLVMInstruction *LLVMTypeAnalyzer::branchStart(LLVMInstruction *end) const
420+
const LLVMInstruction *LLVMTypeAnalyzer::branchStart(const LLVMInstruction *end) const
413421
{
414422
assert(end);
415423
assert(isLoopEnd(end) || isIfEnd(end) || isElse(end));
@@ -434,52 +442,52 @@ LLVMInstruction *LLVMTypeAnalyzer::branchStart(LLVMInstruction *end) const
434442
return ins;
435443
}
436444

437-
bool LLVMTypeAnalyzer::isLoopStart(LLVMInstruction *ins) const
445+
bool LLVMTypeAnalyzer::isLoopStart(const LLVMInstruction *ins) const
438446
{
439447
return (BEGIN_LOOP_INSTRUCTIONS.find(ins->type) != BEGIN_LOOP_INSTRUCTIONS.cend());
440448
}
441449

442-
bool LLVMTypeAnalyzer::isLoopEnd(LLVMInstruction *ins) const
450+
bool LLVMTypeAnalyzer::isLoopEnd(const LLVMInstruction *ins) const
443451
{
444452
return (ins->type == LLVMInstruction::Type::EndLoop);
445453
}
446454

447-
bool LLVMTypeAnalyzer::isIfStart(LLVMInstruction *ins) const
455+
bool LLVMTypeAnalyzer::isIfStart(const LLVMInstruction *ins) const
448456
{
449457
return (ins->type == LLVMInstruction::Type::BeginIf);
450458
}
451459

452-
bool LLVMTypeAnalyzer::isElse(LLVMInstruction *ins) const
460+
bool LLVMTypeAnalyzer::isElse(const LLVMInstruction *ins) const
453461
{
454462
return (ins->type == LLVMInstruction::Type::BeginElse);
455463
}
456464

457-
bool LLVMTypeAnalyzer::isIfEnd(LLVMInstruction *ins) const
465+
bool LLVMTypeAnalyzer::isIfEnd(const LLVMInstruction *ins) const
458466
{
459467
return (ins->type == LLVMInstruction::Type::EndIf);
460468
}
461469

462-
bool LLVMTypeAnalyzer::isVariableRead(LLVMInstruction *ins) const
470+
bool LLVMTypeAnalyzer::isVariableRead(const LLVMInstruction *ins) const
463471
{
464472
return (ins->type == LLVMInstruction::Type::ReadVariable);
465473
}
466474

467-
bool LLVMTypeAnalyzer::isVariableWrite(LLVMInstruction *ins, Variable *var) const
475+
bool LLVMTypeAnalyzer::isVariableWrite(const LLVMInstruction *ins, const Variable *var) const
468476
{
469477
return (ins->type == LLVMInstruction::Type::WriteVariable && ins->workVariable == var);
470478
}
471479

472-
bool LLVMTypeAnalyzer::isListRead(LLVMInstruction *ins) const
480+
bool LLVMTypeAnalyzer::isListRead(const LLVMInstruction *ins) const
473481
{
474482
return (ins->type == LLVMInstruction::Type::GetListItem);
475483
}
476484

477-
bool LLVMTypeAnalyzer::isListWrite(LLVMInstruction *ins, List *list) const
485+
bool LLVMTypeAnalyzer::isListWrite(const LLVMInstruction *ins, const List *list) const
478486
{
479487
return (LIST_WRITE_INSTRUCTIONS.find(ins->type) != LIST_WRITE_INSTRUCTIONS.cend() && ins->workList == list);
480488
}
481489

482-
bool LLVMTypeAnalyzer::isListClear(LLVMInstruction *ins, List *list) const
490+
bool LLVMTypeAnalyzer::isListClear(const LLVMInstruction *ins, const List *list) const
483491
{
484492
return (ins->type == LLVMInstruction::Type::ClearList && ins->workList == list);
485493
}
@@ -498,7 +506,7 @@ Compiler::StaticType LLVMTypeAnalyzer::optimizeRegisterType(LLVMRegister *reg) c
498506
return ret;
499507
}
500508

501-
bool LLVMTypeAnalyzer::isWriteNoOp(LLVMInstruction *ins) const
509+
bool LLVMTypeAnalyzer::isWriteNoOp(const LLVMInstruction *ins) const
502510
{
503511
assert(ins);
504512
assert(!ins->args.empty());
@@ -515,7 +523,7 @@ bool LLVMTypeAnalyzer::isWriteNoOp(LLVMInstruction *ins) const
515523
return false;
516524
}
517525

518-
Compiler::StaticType LLVMTypeAnalyzer::writeValueType(LLVMInstruction *ins, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const
526+
Compiler::StaticType LLVMTypeAnalyzer::writeValueType(const LLVMInstruction *ins, std::unordered_map<const List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const
519527
{
520528
assert(ins);
521529
assert(!ins->args.empty());
@@ -550,7 +558,8 @@ bool LLVMTypeAnalyzer::typesMatch(Compiler::StaticType a, Compiler::StaticType b
550558
return (a == b) && (a != Compiler::StaticType::Unknown);
551559
}
552560

553-
bool LLVMTypeAnalyzer::writeTypesMatch(LLVMInstruction *ins, Compiler::StaticType expectedType, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const
561+
bool LLVMTypeAnalyzer::
562+
writeTypesMatch(const LLVMInstruction *ins, Compiler::StaticType expectedType, std::unordered_map<const List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const
554563
{
555564
return typesMatch(writeValueType(ins, listTypes, visitedInstructions), expectedType);
556565
}

src/engine/internal/llvm/llvmtypeanalyzer.h

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,65 +12,74 @@ struct LLVMRegister;
1212
class LLVMTypeAnalyzer
1313
{
1414
public:
15-
Compiler::StaticType variableType(Variable *var, LLVMInstruction *pos, Compiler::StaticType previousType) const;
16-
Compiler::StaticType variableTypeAfterBranch(Variable *var, LLVMInstruction *start, Compiler::StaticType previousType) const;
15+
Compiler::StaticType variableType(const Variable *var, const LLVMInstruction *pos, Compiler::StaticType previousType) const;
16+
Compiler::StaticType variableTypeAfterBranch(const Variable *var, const LLVMInstruction *start, Compiler::StaticType previousType) const;
1717

18-
Compiler::StaticType listType(List *list, LLVMInstruction *pos, Compiler::StaticType previousType, bool isEmpty) const;
19-
Compiler::StaticType listTypeAfterBranch(List *list, LLVMInstruction *start, Compiler::StaticType previousType, bool isEmpty) const;
18+
Compiler::StaticType listType(const List *list, const LLVMInstruction *pos, Compiler::StaticType previousType, bool isEmpty) const;
19+
Compiler::StaticType listTypeAfterBranch(const List *list, const LLVMInstruction *start, Compiler::StaticType previousType, bool isEmpty) const;
2020

2121
private:
22-
using InstructionSet = std::unordered_set<LLVMInstruction *>;
22+
using InstructionSet = std::unordered_set<const LLVMInstruction *>;
2323

24-
Compiler::StaticType
25-
variableType(Variable *var, LLVMInstruction *pos, Compiler::StaticType previousType, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const;
24+
Compiler::StaticType variableType(
25+
const Variable *var,
26+
const LLVMInstruction *pos,
27+
Compiler::StaticType previousType,
28+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
29+
InstructionSet &visitedInstructions) const;
2630

27-
Compiler::StaticType variableTypeAfterBranch(Variable *var, LLVMInstruction *start, Compiler::StaticType previousType, InstructionSet &visitedInstructions) const;
31+
Compiler::StaticType variableTypeAfterBranch(const Variable *var, const LLVMInstruction *start, Compiler::StaticType previousType, InstructionSet &visitedInstructions) const;
2832

2933
Compiler::StaticType variableTypeAfterBranchFromEnd(
30-
Variable *var,
31-
LLVMInstruction *end,
34+
const Variable *var,
35+
const LLVMInstruction *end,
3236
Compiler::StaticType previousType,
3337
bool &write,
34-
std::unordered_map<List *, Compiler::StaticType> listTypes,
38+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
3539
InstructionSet &visitedInstructions) const;
3640

37-
Compiler::StaticType
38-
listType(List *list, LLVMInstruction *pos, Compiler::StaticType previousType, bool isEmpty, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions)
39-
const;
41+
Compiler::StaticType listType(
42+
const List *list,
43+
const LLVMInstruction *pos,
44+
Compiler::StaticType previousType,
45+
bool isEmpty,
46+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
47+
InstructionSet &visitedInstructions) const;
4048

4149
Compiler::StaticType listTypeAfterBranch(
42-
List *list,
43-
LLVMInstruction *start,
50+
const List *list,
51+
const LLVMInstruction *start,
4452
Compiler::StaticType previousType,
4553
bool isEmpty,
46-
LLVMInstruction *query,
54+
const LLVMInstruction *query,
4755
bool &write,
48-
std::unordered_map<List *, Compiler::StaticType> listTypes,
56+
std::unordered_map<const List *, Compiler::StaticType> listTypes,
4957
InstructionSet &visitedInstructions) const;
5058

5159
bool handleListWrite(Compiler::StaticType writeType, Compiler::StaticType &previousType, bool &isEmpty) const;
5260

53-
LLVMInstruction *branchEnd(LLVMInstruction *start) const;
54-
LLVMInstruction *branchStart(LLVMInstruction *end) const;
61+
const LLVMInstruction *branchEnd(const LLVMInstruction *start) const;
62+
const LLVMInstruction *branchStart(const LLVMInstruction *end) const;
5563

56-
bool isLoopStart(LLVMInstruction *ins) const;
57-
bool isLoopEnd(LLVMInstruction *ins) const;
58-
bool isIfStart(LLVMInstruction *ins) const;
59-
bool isElse(LLVMInstruction *ins) const;
60-
bool isIfEnd(LLVMInstruction *ins) const;
64+
bool isLoopStart(const LLVMInstruction *ins) const;
65+
bool isLoopEnd(const LLVMInstruction *ins) const;
66+
bool isIfStart(const LLVMInstruction *ins) const;
67+
bool isElse(const LLVMInstruction *ins) const;
68+
bool isIfEnd(const LLVMInstruction *ins) const;
6169

62-
bool isVariableRead(LLVMInstruction *ins) const;
63-
bool isVariableWrite(LLVMInstruction *ins, Variable *var) const;
70+
bool isVariableRead(const LLVMInstruction *ins) const;
71+
bool isVariableWrite(const LLVMInstruction *ins, const Variable *var) const;
6472

65-
bool isListRead(LLVMInstruction *ins) const;
66-
bool isListWrite(LLVMInstruction *ins, List *list) const;
67-
bool isListClear(LLVMInstruction *ins, List *list) const;
73+
bool isListRead(const LLVMInstruction *ins) const;
74+
bool isListWrite(const LLVMInstruction *ins, const List *list) const;
75+
bool isListClear(const LLVMInstruction *ins, const List *list) const;
6876

6977
Compiler::StaticType optimizeRegisterType(LLVMRegister *reg) const;
70-
bool isWriteNoOp(LLVMInstruction *ins) const;
71-
Compiler::StaticType writeValueType(LLVMInstruction *ins, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const;
78+
bool isWriteNoOp(const LLVMInstruction *ins) const;
79+
Compiler::StaticType writeValueType(const LLVMInstruction *ins, std::unordered_map<const List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const;
7280
bool typesMatch(Compiler::StaticType a, Compiler::StaticType b) const;
73-
bool writeTypesMatch(LLVMInstruction *ins, Compiler::StaticType expectedType, std::unordered_map<List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const;
81+
bool
82+
writeTypesMatch(const LLVMInstruction *ins, Compiler::StaticType expectedType, std::unordered_map<const List *, Compiler::StaticType> listTypes, InstructionSet &visitedInstructions) const;
7483
};
7584

7685
} // namespace libscratchcpp

0 commit comments

Comments
 (0)