1
2
3
4
5
6 #include <cmajor/cmsxi/Context.hpp>
7 #include <cmajor/cmsxi/Instruction.hpp>
8 #include <cmajor/cmsxi/BasicBlock.hpp>
9
10 namespace cmsxi {
11
12 Context::Context() : currentFunction(nullptr), currentBasicBlock(nullptr), metadata(), currentLineNumber(0)
13 {
14 }
15
16 void Context::AddValue(Value* value)
17 {
18 values.push_back(std::unique_ptr<Value>(value));
19 }
20
21 ConstantValue* Context::GetBoolValue(bool value)
22 {
23 ConstantValue* boolValue = new BoolValue(value);
24 AddValue(boolValue);
25 return boolValue;
26 }
27
28 ConstantValue* Context::GetSByteValue(int8_t value)
29 {
30 ConstantValue* sbyteValue = new SByteValue(value);
31 AddValue(sbyteValue);
32 return sbyteValue;
33 }
34
35 ConstantValue* Context::GetByteValue(uint8_t value)
36 {
37 ConstantValue* byteValue = new ByteValue(value);
38 AddValue(byteValue);
39 return byteValue;
40 }
41
42 ConstantValue* Context::GetShortValue(int16_t value)
43 {
44 ConstantValue* shortValue = new ShortValue(value);
45 AddValue(shortValue);
46 return shortValue;
47 }
48
49 ConstantValue* Context::GetUShortValue(uint16_t value)
50 {
51 ConstantValue* ushortValue = new UShortValue(value);
52 AddValue(ushortValue);
53 return ushortValue;
54 }
55
56 ConstantValue* Context::GetIntValue(int32_t value)
57 {
58 ConstantValue* intValue = new IntValue(value);
59 AddValue(intValue);
60 return intValue;
61 }
62
63 ConstantValue* Context::GetUIntValue(uint32_t value)
64 {
65 ConstantValue* uintValue = new UIntValue(value);
66 AddValue(uintValue);
67 return uintValue;
68 }
69
70 ConstantValue* Context::GetLongValue(int64_t value)
71 {
72 ConstantValue* longValue = new LongValue(value);
73 AddValue(longValue);
74 return longValue;
75 }
76
77 ConstantValue* Context::GetULongValue(uint64_t value)
78 {
79 ConstantValue* ulongValue = new ULongValue(value);
80 AddValue(ulongValue);
81 return ulongValue;
82 }
83
84 ConstantValue* Context::GetFloatValue(float value)
85 {
86 ConstantValue* floatValue = new FloatValue(value);
87 AddValue(floatValue);
88 return floatValue;
89 }
90
91 ConstantValue* Context::GetDoubleValue(double value)
92 {
93 ConstantValue* doubleValue = new DoubleValue(value);
94 AddValue(doubleValue);
95 return doubleValue;
96 }
97
98 ArrayValue* Context::GetArrayValue(Type* arrayType, const std::std::vector<ConstantValue*>&elements, conststd::string&prefix)
99 {
100 ArrayValue* arrayValue = new ArrayValue(arrayType, elements, prefix);
101 AddValue(arrayValue);
102 return arrayValue;
103 }
104
105 StructureValue* Context::GetStructureValue(Type* structureType, const std::std::vector<ConstantValue*>&members)
106 {
107 StructureValue* structureValue = new StructureValue(structureType, members);
108 AddValue(structureValue);
109 return structureValue;
110 }
111
112 StringValue* Context::GetStringValue(Type* stringType, const std::string& value)
113 {
114 StringValue* stringValue = new StringValue(stringType, value);
115 AddValue(stringValue);
116 return stringValue;
117 }
118
119 ConversionValue* Context::GetConversionValue(Type* type, ConstantValue* from)
120 {
121 ConversionValue* conversionValue = new ConversionValue(type, from);
122 AddValue(conversionValue);
123 return conversionValue;
124 }
125
126 ClsIdValue* Context::GetClsIdValue(const std::string& typeId)
127 {
128 ClsIdValue* clsIdValue = new ClsIdValue(typeId);
129 AddValue(clsIdValue);
130 return clsIdValue;
131 }
132
133 Instruction* Context::CreateNot(Value* arg)
134 {
135 Instruction* inst = new NotInstruction(arg);
136 AddLineInfo(inst);
137 currentBasicBlock->AddInstruction(inst);
138 return inst;
139 }
140
141 Instruction* Context::CreateNeg(Value* arg)
142 {
143 Instruction* inst = new NegInstruction(arg);
144 AddLineInfo(inst);
145 currentBasicBlock->AddInstruction(inst);
146 return inst;
147 }
148
149 Instruction* Context::CreateAdd(Value* left, Value* right)
150 {
151 Instruction* inst = new AddInstruction(left, right);
152 AddLineInfo(inst);
153 currentBasicBlock->AddInstruction(inst);
154 return inst;
155 }
156
157 Instruction* Context::CreateSub(Value* left, Value* right)
158 {
159 Instruction* inst = new SubInstruction(left, right);
160 AddLineInfo(inst);
161 currentBasicBlock->AddInstruction(inst);
162 return inst;
163 }
164
165 Instruction* Context::CreateMul(Value* left, Value* right)
166 {
167 Instruction* inst = new MulInstruction(left, right);
168 AddLineInfo(inst);
169 currentBasicBlock->AddInstruction(inst);
170 return inst;
171 }
172
173 Instruction* Context::CreateDiv(Value* left, Value* right)
174 {
175 Instruction* inst = new DivInstruction(left, right);
176 AddLineInfo(inst);
177 currentBasicBlock->AddInstruction(inst);
178 return inst;
179 }
180
181 Instruction* Context::CreateMod(Value* left, Value* right)
182 {
183 Instruction* inst = new ModInstruction(left, right);
184 AddLineInfo(inst);
185 currentBasicBlock->AddInstruction(inst);
186 return inst;
187 }
188
189 Instruction* Context::CreateAnd(Value* left, Value* right)
190 {
191 Instruction* inst = new AndInstruction(left, right);
192 AddLineInfo(inst);
193 currentBasicBlock->AddInstruction(inst);
194 return inst;
195 }
196
197 Instruction* Context::CreateOr(Value* left, Value* right)
198 {
199 Instruction* inst = new OrInstruction(left, right);
200 AddLineInfo(inst);
201 currentBasicBlock->AddInstruction(inst);
202 return inst;
203 }
204
205 Instruction* Context::CreateXor(Value* left, Value* right)
206 {
207 Instruction* inst = new XorInstruction(left, right);
208 AddLineInfo(inst);
209 currentBasicBlock->AddInstruction(inst);
210 return inst;
211 }
212
213 Instruction* Context::CreateShl(Value* left, Value* right)
214 {
215 Instruction* inst = new ShlInstruction(left, right);
216 AddLineInfo(inst);
217 currentBasicBlock->AddInstruction(inst);
218 return inst;
219 }
220
221 Instruction* Context::CreateShr(Value* left, Value* right)
222 {
223 Instruction* inst = new ShrInstruction(left, right);
224 AddLineInfo(inst);
225 currentBasicBlock->AddInstruction(inst);
226 return inst;
227 }
228
229 Instruction* Context::CreateEqual(Value* left, Value* right)
230 {
231 Instruction* inst = new EqualInstruction(left, right);
232 AddLineInfo(inst);
233 currentBasicBlock->AddInstruction(inst);
234 return inst;
235 }
236
237 Instruction* Context::CreateLess(Value* left, Value* right)
238 {
239 Instruction* inst = new LessInstruction(left, right);
240 AddLineInfo(inst);
241 currentBasicBlock->AddInstruction(inst);
242 return inst;
243 }
244
245 Instruction* Context::CreateSignExtend(Value* arg, Type* destType)
246 {
247 Instruction* inst = new SignExtendInstruction(arg, destType);
248 AddLineInfo(inst);
249 currentBasicBlock->AddInstruction(inst);
250 return inst;
251 }
252
253 Instruction* Context::CreateZeroExtend(Value* arg, Type* destType)
254 {
255 Instruction* inst = new ZeroExtendInstruction(arg, destType);
256 AddLineInfo(inst);
257 currentBasicBlock->AddInstruction(inst);
258 return inst;
259 }
260
261 Instruction* Context::CreateTruncate(Value* arg, Type* destType)
262 {
263 Instruction* inst = new TruncateInstruction(arg, destType);
264 AddLineInfo(inst);
265 currentBasicBlock->AddInstruction(inst);
266 return inst;
267 }
268
269 Instruction* Context::CreateBitCast(Value* arg, Type* destType)
270 {
271 Instruction* inst = new BitCastInstruction(arg, destType);
272 AddLineInfo(inst);
273 currentBasicBlock->AddInstruction(inst);
274 return inst;
275 }
276
277 Instruction* Context::CreateIntToFloat(Value* arg, Type* destType)
278 {
279 Instruction* inst = new IntToFloatInstruction(arg, destType);
280 AddLineInfo(inst);
281 currentBasicBlock->AddInstruction(inst);
282 return inst;
283 }
284
285 Instruction* Context::CreateFloatToInt(Value* arg, Type* destType)
286 {
287 Instruction* inst = new FloatToIntInstruction(arg, destType);
288 AddLineInfo(inst);
289 currentBasicBlock->AddInstruction(inst);
290 return inst;
291 }
292
293 Instruction* Context::CreateIntToPtr(Value* arg, Type* destType)
294 {
295 Instruction* inst = new IntToPtrInstruction(arg, destType);
296 AddLineInfo(inst);
297 currentBasicBlock->AddInstruction(inst);
298 return inst;
299 }
300
301 Instruction* Context::CreatePtrToInt(Value* arg, Type* destType)
302 {
303 Instruction* inst = new PtrToIntInstruction(arg, destType);
304 AddLineInfo(inst);
305 currentBasicBlock->AddInstruction(inst);
306 return inst;
307 }
308
309 Instruction* Context::CreateParam(Type* type)
310 {
311 Instruction* inst = new ParamInstruction(type);
312 AddLineInfo(inst);
313 currentBasicBlock->AddInstruction(inst);
314 return inst;
315 }
316
317 Instruction* Context::CreateLocal(Type* type)
318 {
319 Instruction* inst = new LocalInstruction(type);
320 AddLineInfo(inst);
321 currentBasicBlock->AddInstruction(inst);
322 return inst;
323 }
324
325 Instruction* Context::CreateLoad(Value* ptr)
326 {
327 Instruction* inst = new LoadInstruction(ptr);
328 AddLineInfo(inst);
329 currentBasicBlock->AddInstruction(inst);
330 return inst;
331 }
332
333 Instruction* Context::CreateStore(Value* value, Value* ptr)
334 {
335 Instruction* inst = new StoreInstruction(value, ptr);
336 AddLineInfo(inst);
337 currentBasicBlock->AddInstruction(inst);
338 return inst;
339 }
340
341 Instruction* Context::CreateArg(Value* arg)
342 {
343 Instruction* inst = new ArgInstruction(arg);
344 AddLineInfo(inst);
345 currentBasicBlock->AddInstruction(inst);
346 return inst;
347 }
348
349 Instruction* Context::CreateElemAddr(Value* ptr, Value* index)
350 {
351 Instruction* inst = new ElemAddrInstruction(ptr, index);
352 AddLineInfo(inst);
353 currentBasicBlock->AddInstruction(inst);
354 return inst;
355 }
356
357 Instruction* Context::CreatePtrOffset(Value* ptr, Value* offset)
358 {
359 Instruction* inst = new PtrOffsetInstruction(ptr, offset);
360 AddLineInfo(inst);
361 currentBasicBlock->AddInstruction(inst);
362 return inst;
363 }
364
365 Instruction* Context::CreatePtrDiff(Value* leftPtr, Value* rightPtr)
366 {
367 Instruction* inst = new PtrDiffInstruction(leftPtr, rightPtr);
368 AddLineInfo(inst);
369 currentBasicBlock->AddInstruction(inst);
370 return inst;
371 }
372
373 Instruction* Context::CreateCall(Value* function)
374 {
375 Instruction* inst = new CallInstruction(function);
376 AddLineInfo(inst);
377 currentBasicBlock->AddInstruction(inst);
378 return inst;
379 }
380
381 Instruction* Context::CreateRet(Value* value)
382 {
383 Instruction* inst = new RetInstruction(value);
384 AddLineInfo(inst);
385 currentBasicBlock->AddInstruction(inst);
386 return inst;
387 }
388
389 Instruction* Context::CreateJump(BasicBlock* dest)
390 {
391 Instruction* inst = new JumpInstruction(dest);
392 AddLineInfo(inst);
393 currentBasicBlock->AddInstruction(inst);
394 return inst;
395 }
396
397 Instruction* Context::CreateBranch(Value* cond, BasicBlock* trueDest, BasicBlock* falseDest)
398 {
399 Instruction* inst = new BranchInstruction(cond, trueDest, falseDest);
400 AddLineInfo(inst);
401 currentBasicBlock->AddInstruction(inst);
402 return inst;
403 }
404
405 Instruction* Context::CreateSwitch(Value* cond, BasicBlock* defaultDest)
406 {
407 Instruction* inst = new SwitchInstruction(cond, defaultDest);
408 AddLineInfo(inst);
409 currentBasicBlock->AddInstruction(inst);
410 return inst;
411 }
412
413 Instruction* Context::CreateTrap(const std::std::vector<Value*>&args)
414 {
415 Value* b0 = nullptr;
416 Value* b1 = nullptr;
417 Value* b2 = nullptr;
418 int n = args.size();
419 for (int i = 0; i < n; ++i)
420 {
421 Value* arg = args[i];
422 if (i == 0)
423 {
424 b0 = arg;
425 }
426 else if (i == 1)
427 {
428 b1 = arg;
429 }
430 else if (i == 2)
431 {
432 b2 = arg;
433 }
434 else
435 {
436 CreateArg(arg);
437 }
438 }
439 Instruction* inst = new TrapInstruction(b0, b1, b2);
440 AddLineInfo(inst);
441 currentBasicBlock->AddInstruction(inst);
442 return inst;
443 }
444
445 Instruction* Context::CreateNop()
446 {
447 Instruction* inst = new NoOperationInstruction();
448 currentBasicBlock->AddInstruction(inst);
449 return inst;
450 }
451
452 Instruction* Context::CreateSave()
453 {
454 Instruction* inst = new SaveInstruction();
455 currentBasicBlock->AddInstruction(inst);
456 return inst;
457 }
458
459 GlobalVariable* Context::GetOrInsertGlobal(const std::string& name, Type* type)
460 {
461 return dataRepository.GetOrInsertGlobal(name, type);
462 }
463
464 GlobalVariable* Context::CreateGlobalStringPtr(const std::string& stringValue)
465 {
466 return dataRepository.CreateGlobalStringPtr(*this, stringValue);
467 }
468
469 void Context::SetCompileUnitId(const std::string& compileUnitId_)
470 {
471 dataRepository.SetCompileUnitId(compileUnitId_);
472 }
473
474 void Context::AddMDStructItem(MDStruct* mdStruct, const std::string& fieldName, MDItem* item)
475 {
476 mdStruct->AddItem(fieldName, item);
477 }
478
479 void Context::SetCurrentLineNumber(int lineNumber)
480 {
481 if (lineNumber != -1)
482 {
483 currentLineNumber = lineNumber;
484 }
485 }
486
487 void Context::AddLineInfo(Instruction* inst)
488 {
489 if (currentLineNumber != 0 && !inst->IsNoOperation())
490 {
491 MDStructRef* lineNumberInfo = nullptr;
492 auto it = lineNumberInfoMap.find(currentLineNumber);
493 if (it != lineNumberInfoMap.cend())
494 {
495 lineNumberInfo = it->second;
496 }
497 else
498 {
499 MDStruct* lineNumberStruct = metadata.CreateMDStruct();
500 lineNumberStruct->AddItem("nodeType", metadata.CreateMDLong(lineInfoNodeType));
501 lineNumberStruct->AddItem("line", metadata.CreateMDLong(currentLineNumber));
502 lineNumberInfo = metadata.CreateMDStructRef(lineNumberStruct->Id());
503 lineNumberInfoMap[currentLineNumber] = lineNumberInfo;
504 }
505 inst->SetMetadataRef(lineNumberInfo);
506 }
507 }
508
509 MDStructRef* Context::GetMDStructRefForSourceFile(const std::string& sourceFileName)
510 {
511 auto it = sourceFileMap.find(sourceFileName);
512 if (it != sourceFileMap.cend())
513 {
514 return it->second;
515 }
516 else
517 {
518 MDStruct* sourceFileStruct = metadata.CreateMDStruct();
519 sourceFileStruct->AddItem("nodeType", metadata.CreateMDLong(fileInfoNodeType));
520 sourceFileStruct->AddItem("sourceFileName", metadata.CreateMDString(sourceFileName));
521 MDStructRef* sourceFileNameRef = metadata.CreateMDStructRef(sourceFileStruct->Id());
522 sourceFileMap[sourceFileName] = sourceFileNameRef;
523 return sourceFileNameRef;
524 }
525 }
526
527 void Context::SetMetadataRef(Instruction* inst, MDStructRef* metadataRef)
528 {
529 inst->SetMetadataRef(metadataRef);
530 }
531
532 }