Преглед изворни кода

Refactor function definition lowering. (#5014)

Some refactoring to start adding lowering of function definition
generics.
Alina Sbirlea пре 1 година
родитељ
комит
7a9af69595
2 измењених фајлова са 28 додато и 3 уклоњено
  1. 15 3
      toolchain/lower/file_context.cpp
  2. 13 0
      toolchain/lower/file_context.h

+ 15 - 3
toolchain/lower/file_context.cpp

@@ -4,6 +4,7 @@
 
 #include "toolchain/lower/file_context.h"
 
+#include "common/check.h"
 #include "common/vlog.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Sequence.h"
@@ -184,6 +185,8 @@ auto FileContext::GetOrCreateFunction(SemIR::FunctionId function_id,
   // TODO: Add this function to a list of specific functions whose definitions
   // we need to emit.
   specific_functions_[specific_id.index] = result;
+  // TODO: Should this be a pair of <function_id, specific_id> ?
+  specific_function_definitions_.push_back(specific_id);
   return result;
 }
 
@@ -315,13 +318,22 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id)
     return;
   }
 
+  BuildFunctionBody(function_id, function, llvm_function);
+}
+
+auto FileContext::BuildFunctionBody(SemIR::FunctionId function_id,
+                                    const SemIR::Function& function,
+                                    llvm::Function* llvm_function,
+                                    SemIR::SpecificId specific_id) -> void {
+  const auto& body_block_ids = function.body_block_ids;
+  CARBON_DCHECK(llvm_function, "LLVM Function not found when lowering body.");
+  CARBON_DCHECK(!body_block_ids.empty(),
+                "No function body blocks found during lowering.");
+
   FunctionContext function_lowering(*this, llvm_function,
                                     BuildDISubprogram(function, llvm_function),
                                     vlog_stream_);
 
-  // TODO: Pass in a specific ID for generic functions.
-  const auto specific_id = SemIR::SpecificId::None;
-
   // Add parameters to locals.
   // TODO: This duplicates the mapping between sem_ir instructions and LLVM
   // function parameters that was already computed in BuildFunctionDecl.

+ 13 - 0
toolchain/lower/file_context.h

@@ -11,6 +11,7 @@
 #include "llvm/IR/Module.h"
 #include "toolchain/check/sem_ir_loc_diagnostic_emitter.h"
 #include "toolchain/sem_ir/file.h"
+#include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst_namer.h"
 
 namespace Carbon::Lower {
@@ -105,6 +106,12 @@ class FileContext {
   // declaration with no definition, does nothing.
   auto BuildFunctionDefinition(SemIR::FunctionId function_id) -> void;
 
+  // Builds a functions body. Common functionality for all functions.
+  auto BuildFunctionBody(
+      SemIR::FunctionId function_id, const SemIR::Function& function,
+      llvm::Function* llvm_function,
+      SemIR::SpecificId specific_id = SemIR::SpecificId::None) -> void;
+
   // Build the DISubprogram metadata for the given function.
   auto BuildDISubprogram(const SemIR::Function& function,
                          const llvm::Function* llvm_function)
@@ -152,6 +159,12 @@ class FileContext {
   // `SpecificId` indexes. We resize this directly to the correct size.
   llvm::SmallVector<llvm::Function*, 0> specific_functions_;
 
+  // Maps which specific functions are generics that need to have their
+  // definitions lowered after the lowering of other definitions.
+  // This list may grow while lowering generic definitions from this list.
+  // The list uses the `SpecificId` to index into specific_functions_.
+  llvm::SmallVector<SemIR::SpecificId, 10> specific_function_definitions_;
+
   // Provides lowered versions of types.
   // Vector indexes correspond to `TypeId` indexes for non-symbolic types. We
   // resize this directly to the (often large) correct size.