lowering_function_context.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. #include "toolchain/lowering/lowering_function_context.h"
  5. #include "toolchain/semantics/semantics_ir.h"
  6. namespace Carbon {
  7. LoweringFunctionContext::LoweringFunctionContext(
  8. LoweringContext& lowering_context, llvm::Function* function)
  9. : lowering_context_(&lowering_context),
  10. function_(function),
  11. builder_(lowering_context.llvm_context()) {}
  12. auto LoweringFunctionContext::GetBlock(SemanticsNodeBlockId block_id)
  13. -> llvm::BasicBlock* {
  14. llvm::BasicBlock*& entry = blocks_[block_id];
  15. if (!entry) {
  16. entry = llvm::BasicBlock::Create(llvm_context(), "", function_);
  17. }
  18. return entry;
  19. }
  20. auto LoweringFunctionContext::TryToReuseBlock(SemanticsNodeBlockId block_id,
  21. llvm::BasicBlock* block) -> bool {
  22. if (!blocks_.insert({block_id, block}).second) {
  23. return false;
  24. }
  25. if (block == synthetic_block_) {
  26. synthetic_block_ = nullptr;
  27. }
  28. return true;
  29. }
  30. auto LoweringFunctionContext::GetBlockArg(SemanticsNodeBlockId block_id,
  31. SemanticsTypeId type_id)
  32. -> llvm::PHINode* {
  33. llvm::BasicBlock* block = GetBlock(block_id);
  34. // Find the existing phi, if any.
  35. auto phis = block->phis();
  36. if (!phis.empty()) {
  37. CARBON_CHECK(std::next(phis.begin()) == phis.end())
  38. << "Expected at most one phi, found "
  39. << std::distance(phis.begin(), phis.end());
  40. return &*phis.begin();
  41. }
  42. // The number of predecessor slots to reserve.
  43. static constexpr unsigned NumReservedPredecessors = 2;
  44. auto* phi = llvm::PHINode::Create(GetType(type_id), NumReservedPredecessors);
  45. phi->insertInto(block, block->begin());
  46. return phi;
  47. }
  48. auto LoweringFunctionContext::CreateSyntheticBlock() -> llvm::BasicBlock* {
  49. synthetic_block_ = llvm::BasicBlock::Create(llvm_context(), "", function_);
  50. return synthetic_block_;
  51. }
  52. auto LoweringFunctionContext::GetLocalLoaded(SemanticsNodeId node_id)
  53. -> llvm::Value* {
  54. auto* value = GetLocal(node_id);
  55. if (llvm::isa<llvm::AllocaInst, llvm::GetElementPtrInst>(value)) {
  56. auto* load_type = GetType(semantics_ir().GetNode(node_id).type_id());
  57. return builder().CreateLoad(load_type, value);
  58. } else {
  59. // No load is needed.
  60. return value;
  61. }
  62. }
  63. } // namespace Carbon