GCC Code Coverage Report


src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
49 / 49
100.0%
Branches:
4 / 4, 2 excl
100.0%
Functions:
5 / 5
100.0%

irgenerator/metadata-generator.spice
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 // Std imports
4 import "std/data/vector";
5 import "std/bindings/llvm/llvm" as llvm;
6
7 // Own imports
8 import "@/irgenerator/ir-generator";
9 import "@/global/type-registry";
10 import "@/symboltablebuilder/qual-type";
11
12 /**
13 * Generates the metadata, that is attached to instructions (branch weights, type metadata and TBAA metadata).
14 *
15 * llvm::MDBuilder has no counterpart in the LLVM C API, so the metadata nodes are built by hand with the same structure.
16 */
17 public type MetadataGenerator struct {
18 IRGenerator* irGenerator
19 llvm::Metadata tbaaRoot
20 llvm::Metadata omnipotentByte
21 }
22
23 3499 public p MetadataGenerator.ctor(IRGenerator* irGenerator) {
24 3499 this.irGenerator = irGenerator;
25 // Like mdBuilder.createTBAARoot("Simple Spice TBAA")
26 3499 Vector<llvm::Metadata> rootOperands;
27 3499 rootOperands.pushBack(llvm::getMDString(*irGenerator.context, String("Simple Spice TBAA")));
28 3499 this.tbaaRoot = llvm::getMDNode(*irGenerator.context, rootOperands);
29 3499 this.omnipotentByte = this.createTBAAScalarTypeNode(String("omnipotent byte"), this.tbaaRoot);
30 3499 }
31
32 4911 public p MetadataGenerator.generateBranchWeightsMetadata(llvm::Value jumpInst, Likelihood likeliness) {
33 4911 assert likeliness != Likelihood::UNSPECIFIED;
34 4911 const bool likely = likeliness == Likelihood::LIKELY;
35 // Like mdBuilder.createLikelyBranchWeights() / mdBuilder.createUnlikelyBranchWeights()
36
2/2
✓ Branch 0 taken 4818 times.
✓ Branch 1 taken 93 times.
4911 const unsigned int trueWeight = likely ? llvm::LIKELY_BRANCH_WEIGHT : llvm::UNLIKELY_BRANCH_WEIGHT;
37
2/2
✓ Branch 0 taken 4818 times.
✓ Branch 1 taken 93 times.
4911 const unsigned int falseWeight = likely ? llvm::UNLIKELY_BRANCH_WEIGHT : llvm::LIKELY_BRANCH_WEIGHT;
38 4911 llvm::IRBuilder* builder = this.irGenerator.builder;
39 4911 Vector<llvm::Metadata> operands;
40 4911 operands.pushBack(llvm::getMDString(*this.irGenerator.context, String("branch_weights")));
41 4911 operands.pushBack(llvm::getConstantAsMetadata(builder.getInt32(trueWeight)));
42 4911 operands.pushBack(llvm::getConstantAsMetadata(builder.getInt32(falseWeight)));
43 4911 const llvm::Metadata profMetadata = llvm::getMDNode(*this.irGenerator.context, operands);
44 4911 jumpInst.setMetadata("prof", profMetadata);
45 4911 }
46
47 12 public p MetadataGenerator.generateTypeMetadata(llvm::Value inst, const QualType& qualType) {
48 12 TypeRegistry& typeRegistry = this.irGenerator.resourceManager.typeRegistry;
49 12 const unsigned long typeHash = typeRegistry.getTypeHash(*qualType.getType());
50
51 12 llvm::IRBuilder* builder = this.irGenerator.builder;
52 12 Vector<llvm::Metadata> operands;
53 12 operands.pushBack(llvm::getConstantAsMetadata(builder.getInt64(typeHash)));
54 12 operands.pushBack(llvm::getMDString(*this.irGenerator.context, qualType.getName(true, true)));
55 12 const llvm::Metadata typeMetadata = llvm::getMDNode(*this.irGenerator.context, operands);
56
57 12 inst.setMetadata("type", typeMetadata);
58 12 }
59
60 24 public p MetadataGenerator.generateTBAAMetadata(llvm::Value inst, const QualType& qualType) {
61 24 const String typeName = qualType.getName(true, true);
62 24 const llvm::Metadata tbaaTypeNode = this.createTBAAScalarTypeNode(typeName, this.omnipotentByte);
63 24 llvm::IRBuilder* builder = this.irGenerator.builder;
64 24 Vector<llvm::Metadata> operands;
65 24 operands.pushBack(tbaaTypeNode);
66 24 operands.pushBack(tbaaTypeNode);
67 24 operands.pushBack(llvm::getConstantAsMetadata(builder.getInt64(0)));
68 24 const llvm::Metadata tbaaAccessTag = llvm::getMDNode(*this.irGenerator.context, operands);
69
70 24 inst.setMetadata("tbaa", tbaaAccessTag);
71 24 }
72
73 // Like mdBuilder.createTBAAScalarTypeNode(name, parent)
74 3523 f<llvm::Metadata> MetadataGenerator.createTBAAScalarTypeNode(const String& name, llvm::Metadata parent) {
75 3523 llvm::IRBuilder* builder = this.irGenerator.builder;
76 3523 Vector<llvm::Metadata> operands;
77 3523 operands.pushBack(llvm::getMDString(*this.irGenerator.context, name));
78 3523 operands.pushBack(parent);
79 3523 operands.pushBack(llvm::getConstantAsMetadata(builder.getInt64(0)));
80 7046 return llvm::getMDNode(*this.irGenerator.context, operands);
81 3523 }
82