lowering_context.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_LOWERING_LOWERING_CONTEXT_H_
  5. #define CARBON_TOOLCHAIN_LOWERING_LOWERING_CONTEXT_H_
  6. #include "llvm/IR/IRBuilder.h"
  7. #include "llvm/IR/LLVMContext.h"
  8. #include "llvm/IR/Module.h"
  9. #include "toolchain/semantics/semantics_ir.h"
  10. #include "toolchain/semantics/semantics_node.h"
  11. namespace Carbon {
  12. // Context and shared functionality for lowering handlers.
  13. class LoweringContext {
  14. public:
  15. explicit LoweringContext(llvm::LLVMContext& llvm_context,
  16. llvm::StringRef module_name,
  17. const SemanticsIR& semantics_ir);
  18. // Lowers the SemanticsIR to LLVM IR. Should only be called once, and handles
  19. // the main execution loop.
  20. auto Run() -> std::unique_ptr<llvm::Module>;
  21. auto HasLoweredNode(SemanticsNodeId node_id) -> bool {
  22. return !lowered_nodes_[node_id.index].isNull();
  23. }
  24. // Returns a type for the given node. May construct and cache the type
  25. // if it hasn't yet been built.
  26. auto GetLoweredNodeAsType(SemanticsNodeId node_id) -> llvm::Type*;
  27. // Returns a value for the given node.
  28. auto GetLoweredNodeAsValue(SemanticsNodeId node_id) -> llvm::Value* {
  29. CARBON_CHECK(lowered_nodes_[node_id.index].is<llvm::Value*>())
  30. << node_id << ": isNull == " << lowered_nodes_[node_id.index].isNull();
  31. return lowered_nodes_[node_id.index].get<llvm::Value*>();
  32. }
  33. // Sets the value for the given node.
  34. auto SetLoweredNodeAsValue(SemanticsNodeId node_id, llvm::Value* value) {
  35. CARBON_CHECK(lowered_nodes_[node_id.index].isNull()) << node_id;
  36. lowered_nodes_[node_id.index] = value;
  37. }
  38. auto llvm_context() -> llvm::LLVMContext& { return *llvm_context_; }
  39. auto llvm_module() -> llvm::Module& { return *llvm_module_; }
  40. auto builder() -> llvm::IRBuilder<>& { return builder_; }
  41. auto semantics_ir() -> const SemanticsIR& { return *semantics_ir_; }
  42. auto todo_blocks() -> llvm::SmallVector<
  43. std::pair<llvm::BasicBlock*, SemanticsNodeBlockId>>& {
  44. return todo_blocks_;
  45. }
  46. private:
  47. // Runs lowering for a block.
  48. auto LowerBlock(SemanticsNodeBlockId block_id) -> void;
  49. // Builds the type for the given node, which should then be cached by the
  50. // caller.
  51. auto BuildLoweredNodeAsType(SemanticsNodeId node_id) -> llvm::Type*;
  52. // State for building the LLVM IR.
  53. llvm::LLVMContext* llvm_context_;
  54. std::unique_ptr<llvm::Module> llvm_module_;
  55. llvm::IRBuilder<> builder_;
  56. // The input Semantics IR.
  57. const SemanticsIR* const semantics_ir_;
  58. // Blocks which we've observed and need to lower.
  59. llvm::SmallVector<std::pair<llvm::BasicBlock*, SemanticsNodeBlockId>>
  60. todo_blocks_;
  61. // Maps nodes in SemanticsIR to a lowered value. This will have one entry per
  62. // node, and will be non-null when lowered. It's expected to be sparse during
  63. // execution because while expressions will have entries, statements won't.
  64. // TODO: Long-term, we should examine the practical trade-offs of making this
  65. // a map; a map may end up lower memory consumption, but a vector offers cache
  66. // efficiency and better performance. As a consequence, the right choice is
  67. // unclear.
  68. llvm::SmallVector<llvm::PointerUnion<llvm::Type*, llvm::Value*>>
  69. lowered_nodes_;
  70. };
  71. // Declare handlers for each SemanticsIR node.
  72. #define CARBON_SEMANTICS_NODE_KIND(Name) \
  73. auto LoweringHandle##Name(LoweringContext& context, SemanticsNodeId node_id, \
  74. SemanticsNode node) \
  75. ->void;
  76. #include "toolchain/semantics/semantics_node_kind.def"
  77. } // namespace Carbon
  78. #endif // CARBON_TOOLCHAIN_LOWERING_LOWERING_CONTEXT_H_