• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_TORQUE_TORQUE_CODE_GENERATOR_H_
6 #define V8_TORQUE_TORQUE_CODE_GENERATOR_H_
7 
8 #include <iostream>
9 
10 #include "src/torque/cfg.h"
11 #include "src/torque/declarable.h"
12 
13 namespace v8 {
14 namespace internal {
15 namespace torque {
16 
17 class TorqueCodeGenerator {
18  public:
TorqueCodeGenerator(const ControlFlowGraph & cfg,std::ostream & out)19   TorqueCodeGenerator(const ControlFlowGraph& cfg, std::ostream& out)
20       : cfg_(cfg),
21         out_(&out),
22         out_decls_(&out),
23         previous_position_(SourcePosition::Invalid()) {}
24 
25  protected:
26   const ControlFlowGraph& cfg_;
27   std::ostream* out_;
28   std::ostream* out_decls_;
29   size_t fresh_id_ = 0;
30   SourcePosition previous_position_;
31   std::map<DefinitionLocation, std::string> location_map_;
32 
DefinitionToVariable(const DefinitionLocation & location)33   std::string DefinitionToVariable(const DefinitionLocation& location) {
34     if (location.IsPhi()) {
35       std::stringstream stream;
36       stream << "phi_bb" << location.GetPhiBlock()->id() << "_"
37              << location.GetPhiIndex();
38       return stream.str();
39     } else if (location.IsParameter()) {
40       auto it = location_map_.find(location);
41       DCHECK_NE(it, location_map_.end());
42       return it->second;
43     } else {
44       DCHECK(location.IsInstruction());
45       auto it = location_map_.find(location);
46       if (it == location_map_.end()) {
47         it = location_map_.insert(std::make_pair(location, FreshNodeName()))
48                  .first;
49       }
50       return it->second;
51     }
52   }
53 
SetDefinitionVariable(const DefinitionLocation & definition,const std::string & str)54   void SetDefinitionVariable(const DefinitionLocation& definition,
55                              const std::string& str) {
56     DCHECK_EQ(location_map_.find(definition), location_map_.end());
57     location_map_.insert(std::make_pair(definition, str));
58   }
59 
out()60   std::ostream& out() { return *out_; }
decls()61   std::ostream& decls() { return *out_decls_; }
62 
63   static bool IsEmptyInstruction(const Instruction& instruction);
64   virtual void EmitSourcePosition(SourcePosition pos,
65                                   bool always_emit = false) = 0;
66 
FreshNodeName()67   std::string FreshNodeName() { return "tmp" + std::to_string(fresh_id_++); }
FreshCatchName()68   std::string FreshCatchName() { return "catch" + std::to_string(fresh_id_++); }
FreshLabelName()69   std::string FreshLabelName() { return "label" + std::to_string(fresh_id_++); }
BlockName(const Block * block)70   std::string BlockName(const Block* block) {
71     return "block" + std::to_string(block->id());
72   }
73 
74   void EmitInstruction(const Instruction& instruction,
75                        Stack<std::string>* stack);
76 
77   template <typename T>
EmitIRAnnotation(const T & instruction,Stack<std::string> * stack)78   void EmitIRAnnotation(const T& instruction, Stack<std::string>* stack) {
79     out() << "    // " << instruction
80           << ", starting stack size: " << stack->Size() << "\n";
81   }
82 
83 #define EMIT_INSTRUCTION_DECLARATION(T) \
84   void EmitInstruction(const T& instruction, Stack<std::string>* stack);
85   TORQUE_BACKEND_AGNOSTIC_INSTRUCTION_LIST(EMIT_INSTRUCTION_DECLARATION)
86 #undef EMIT_INSTRUCTION_DECLARATION
87 
88 #define EMIT_INSTRUCTION_DECLARATION(T)              \
89   virtual void EmitInstruction(const T& instruction, \
90                                Stack<std::string>* stack) = 0;
91   TORQUE_BACKEND_DEPENDENT_INSTRUCTION_LIST(EMIT_INSTRUCTION_DECLARATION)
92 #undef EMIT_INSTRUCTION_DECLARATION
93 };
94 
95 }  // namespace torque
96 }  // namespace internal
97 }  // namespace v8
98 
99 #endif  // V8_TORQUE_TORQUE_CODE_GENERATOR_H_
100