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 | 4911 | const unsigned int trueWeight = likely ? llvm::LIKELY_BRANCH_WEIGHT : llvm::UNLIKELY_BRANCH_WEIGHT; | |
| 37 | 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 |