0
|
1 module dmd.backend.block;
|
|
2
|
|
3 import dmd.backend.elem;
|
|
4 import dmd.backend.LIST;
|
|
5 import dmd.backend.regm_t;
|
|
6 import dmd.backend.Symbol;
|
|
7 import dmd.backend.Srcpos;
|
|
8 import dmd.backend.code;
|
|
9 import dmd.backend.SYMIDX;
|
|
10 import dmd.backend.vec_t;
|
|
11 import dmd.backend.targ_types;
|
|
12 import dmd.backend.con_t;
|
|
13
|
|
14 struct block
|
|
15 {
|
|
16 union
|
|
17 {
|
|
18 elem* Belem; // pointer to elem tree
|
|
19 list_t Blist; // list of expressions
|
|
20 };
|
|
21
|
|
22 block* Bnext; // pointer to next block in list
|
|
23 list_t Bsucc; // linked list of pointers to successors
|
|
24 // of this block
|
|
25 list_t Bpred; // and the predecessor list
|
|
26
|
|
27 int Bindex; // into created object stack
|
|
28 int Bendindex; // index at end of block
|
|
29 block* Btry; // BCtry,BC_try: enclosing try block, if any
|
|
30 // BC???: if in try-block, points to BCtry or BC_try
|
|
31 // note that can't have a BCtry and BC_try in
|
|
32 // the same function.
|
|
33 union
|
|
34 {
|
|
35 targ_llong *Bswitch; // BCswitch: pointer to switch data
|
|
36 struct
|
|
37 {
|
|
38 regm_t usIasmregs; // Registers modified
|
|
39 ubyte bIasmrefparam; // References parameters?
|
|
40 }
|
|
41
|
|
42 struct
|
|
43 {
|
|
44 Symbol* catchvar; // __throw() fills in this
|
|
45 }
|
|
46
|
|
47 struct
|
|
48 {
|
|
49 Symbol* catchtype; // one type for each catch block
|
|
50 }
|
|
51
|
|
52 struct
|
|
53 {
|
|
54 Symbol* jcatchvar; // __j_throw() fills in this
|
|
55 int Bscope_index; // index into scope table
|
|
56 int Blast_index; // enclosing index into scope table
|
|
57 }
|
|
58 }
|
|
59
|
|
60 public alias catchtype Bcatchtype;
|
|
61
|
|
62 Srcpos Bsrcpos; // line number (0 if not known)
|
|
63 ubyte BC; // exit condition (enum BC)
|
|
64 // NEW
|
|
65 ubyte Balign; // alignment
|
|
66
|
|
67 ushort Bflags; // flags (BFLxxxx)
|
|
68 code* Bcode; // code generated for this block
|
|
69
|
|
70 uint Bweight; // relative number of times this block
|
|
71 // is executed (optimizer and codegen)
|
|
72
|
|
73 uint Bdfoidx; // index of this block in dfo[]
|
|
74 union
|
|
75 {
|
|
76 // CPP
|
|
77 struct
|
|
78 {
|
|
79 SYMIDX symstart; // (symstart <= symnum < symend) Symbols
|
|
80 SYMIDX symend; // are declared in this block
|
|
81 block* endscope; // block that forms the end of the
|
|
82 // scope for the declared Symbols
|
|
83 uint blknum; // position of block from startblock
|
|
84 Symbol* Binitvar; // !=NULL points to an auto variable with
|
|
85 // an explicit or implicit initializer
|
|
86 block* gotolist; // BCtry, BCcatch: backward list of try scopes
|
|
87 block* gotothread; // BCgoto: threaded list of goto's to
|
|
88 // unknown labels
|
|
89 }
|
|
90
|
|
91 // OPTIMIZER
|
|
92 struct
|
|
93 {
|
|
94 vec_t Bdom; // mask of dominators for this block
|
|
95 vec_t Binrd;
|
|
96 vec_t Boutrd; // IN and OUT for reaching definitions
|
|
97 vec_t Binlv;
|
|
98 vec_t Boutlv; // IN and OUT for live variables
|
|
99 vec_t Bin;
|
|
100 vec_t Bout; // IN and OUT for other flow analyses
|
|
101 vec_t Bgen;
|
|
102 vec_t Bkill; // pointers to bit vectors used by data
|
|
103 // flow analysis
|
|
104
|
|
105 // BCiftrue can have different vectors for the 2nd successor:
|
|
106 vec_t Bout2;
|
|
107 vec_t Bgen2;
|
|
108 vec_t Bkill2;
|
|
109 }
|
|
110
|
|
111 // CODGEN
|
|
112 struct
|
|
113 {
|
|
114 targ_size_t Btablesize; // BCswitch, BCjmptab
|
|
115 targ_size_t Btableoffset; // BCswitch, BCjmptab
|
|
116 targ_size_t Boffset; // code offset of start of this block
|
|
117 targ_size_t Bsize; // code size of this block
|
|
118 con_t Bregcon; // register state at block exit
|
|
119 targ_size_t Btryoff; // BCtry: offset of try block data
|
|
120 }
|
|
121 }
|
|
122 }
|
|
123
|
|
124 enum BFL
|
|
125 {
|
|
126 BFLvisited = 1, // set if block is visited
|
|
127 BFLmark = 2, // set if block is visited
|
|
128 BFLjmpoptdone = 4, // set when no more jump optimizations
|
|
129 // are possible for this block
|
|
130 BFLnostackopt = 8, // set when stack elimination should not
|
|
131 // be done
|
|
132 ///version (NTEXCEPTIONS) {
|
|
133 BFLehcode = 0x10, // set when we need to load exception code
|
|
134 BFLunwind = 0x1000, // do local_unwind following block
|
|
135 ///}
|
|
136 ///version (TARGET_POWERPC) {
|
|
137 /// BFLstructret = 0x10, /* Set if a struct return is changed to
|
|
138 /// block type BCret. This is done to avoid
|
|
139 /// error messages */
|
|
140 ///}
|
|
141 BFLnomerg = 0x20, // do not merge with other blocks
|
|
142 ///version (TX86) {
|
|
143 BFLprolog = 0x80, // generate function prolog
|
|
144 BFLepilog = 0x100, // generate function epilog
|
|
145 BFLrefparam = 0x200, // referenced parameter
|
|
146 BFLreflocal = 0x400, // referenced local
|
|
147 BFLoutsideprolog = 0x800, // outside function prolog/epilog
|
|
148 BFLlabel = 0x2000, // block preceded by label
|
|
149 ///} else {
|
|
150 /// BFLlooprt = 0x40, // set if looprotate() changes it's Bnext
|
|
151 ///}
|
|
152 BFLvolatile = 0x4000, // block is volatile
|
|
153 } |