Skip to content

Commit 23505a4

Browse files
committed
Document most entries
Save TBAA, it'll be its own Slog
1 parent 2ccb4f7 commit 23505a4

File tree

4 files changed

+233
-51
lines changed

4 files changed

+233
-51
lines changed

Sources/LLVM/IRMetadata.swift

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public protocol _IRMetadataInitializerHack {
2222
/// Metadata does not have a type, and is not a value. If referenced from a call
2323
/// instruction, it uses the metadata type.
2424
///
25+
/// Debug Information
26+
/// =================
27+
///
2528
/// The idea of LLVM debugging information is to capture how the important
2629
/// pieces of the source-language’s Abstract Syntax Tree map onto LLVM code.
2730
/// LLVM takes a number of positions on the impact of the broader compilation
@@ -389,37 +392,60 @@ public struct NameSpaceMetadata: DIScope {
389392
}
390393

391394
/// `MDString` nodes represent string constants in metadata nodes.
392-
public struct MDString: IRMetadata {
395+
public struct MDString: IRMetadata, ExpressibleByStringLiteral {
396+
public typealias StringLiteralType = String
397+
393398
private let llvm: LLVMMetadataRef
394399

395400
public init(llvm: LLVMMetadataRef) {
396401
self.llvm = llvm
397402
}
398403

404+
/// Create an `MDString` node from the given string value.
405+
///
406+
/// - Parameters:
407+
/// - value: The string value to assign to this metadata node.
399408
public init(_ value: String) {
400409
self.llvm = LLVMValueAsMetadata(LLVMMDString(value, UInt32(value.count)))
401410
}
402411

412+
public init(stringLiteral value: String) {
413+
self.llvm = LLVMValueAsMetadata(LLVMMDString(value, UInt32(value.count)))
414+
}
415+
403416
public func asMetadata() -> LLVMMetadataRef {
404417
return llvm
405418
}
406419
}
407420

408-
/// `MDNode` nodes represent generic metadata nodes.
421+
/// `MDNode` objects represent generic nodes in a metadata graph.
422+
///
423+
/// A metadata node is a tuple of references to other metadata. In general,
424+
/// metadata graphs are acyclic and terminate in metadata nodes without
425+
/// operands.
409426
public struct MDNode: IRMetadata {
410427
private let llvm: LLVMMetadataRef
411428

412429
public init(llvm: LLVMMetadataRef) {
413430
self.llvm = llvm
414431
}
415432

433+
/// Create a metadata node in the given context with the given operands.
434+
///
435+
/// - Parameters:
436+
/// - context: The context to allocate the node in.
437+
/// - operands: The operands to attach to the metadata node.
416438
public init(in context: Context = .global, operands: [IRMetadata]) {
417439
var operands = operands.map { $0.asMetadata() as Optional }
418440
self.llvm = operands.withUnsafeMutableBufferPointer { buf in
419441
return LLVMMDNodeInContext2(context.llvm, buf.baseAddress!, UInt32(buf.count))
420442
}
421443
}
422444

445+
/// Create a metadata node with the value of a given constant.
446+
///
447+
/// - Parameters:
448+
/// - constant: The constant value to attach to the node.
423449
public init(constant: IRConstant) {
424450
self.llvm = LLVMValueAsMetadata(constant.asLLVM())
425451
}
@@ -429,20 +455,56 @@ public struct MDNode: IRMetadata {
429455
}
430456
}
431457

458+
/// Represents a temporary metadata node.
459+
///
460+
/// Temporary metadata nodes aid in the construction of cyclic metadata. The
461+
/// typical construction pattern is usually as follows:
462+
///
463+
/// // Allocate a temporary temp node
464+
/// let temp = TemporaryMDNode(in: context, operands: [])
465+
/// // Prepare the operands to the metadata node...
466+
/// var ops = [IRMetadata]()
467+
/// // ...
468+
/// // Create the real node
469+
/// let root = MDNode(in: context, operands: ops)
470+
///
471+
/// At this point we have the following metadata structure:
472+
///
473+
/// // !0 = metadata !{} <- temp
474+
/// // !1 = metadata !{metadata !0} <- root
475+
/// // Replace the temp operand with the root node
476+
///
477+
/// The knot is tied by RAUW'ing the temporary node:
478+
///
479+
/// temp.replaceAllUses(with: root)
480+
/// // We now have
481+
/// // !1 = metadata !{metadata !1} <- self-referential root
482+
///
483+
/// - Warning: It is critical that temporary metadata nodes be "RAUW'd"
484+
/// (replace-all-uses-with) before the metadata graph is finalized. After
485+
/// that time, all remaining temporary metadata nodes will become unresolved
486+
/// metadata.
432487
public class TemporaryMDNode: IRMetadata {
433488
private let llvm: LLVMMetadataRef
434489

435490
required public init(llvm: LLVMMetadataRef) {
436491
self.llvm = llvm
437492
}
438493

494+
/// Create a new temporary metadata node in the given context with the
495+
/// given operands.
496+
///
497+
/// - Parameters:
498+
/// - context: The context to allocate the node in.
499+
/// - operands: The operands to attach to the metadata node.
439500
public init(in context: Context = .global, operands: [IRMetadata]) {
440501
var operands = operands.map { $0.asMetadata() as Optional }
441502
self.llvm = operands.withUnsafeMutableBufferPointer { buf in
442503
return LLVMTemporaryMDNode(context.llvm, buf.baseAddress!, buf.count)
443504
}
444505
}
445506

507+
/// Deinitialize this value and dispose of its resources.
446508
deinit {
447509
LLVMDisposeTemporaryMDNode(self.llvm)
448510
}

0 commit comments

Comments
 (0)