source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/core/optimize.rb@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 15.7 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2018 by TOPPERS Project
7#--
8# 上記著作権者
9は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再é…
12å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再é…
18å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
19å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
20# 者
21マニュアルなど)に,上記の著作権表示,この利用条件および下記
22# の無保証規定を掲載すること.
23# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24# 用できない形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
26# と.
27# (a) 再é…
28å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
29マニュアルなど)に,上記の著
30# 作権表示,この利用条件および下記の無保証規定を掲載すること.
31# (b) 再é…
32å¸ƒã®å½¢æ…
33‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
34# 報告すること.
35# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36# 害からも,上記著作権者
37およびTOPPERSプロジェクトをå…
38è²¬ã™ã‚‹ã“と.
39# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
40# 由に基づく請求からも,上記著作権者
41およびTOPPERSプロジェクトを
42# å…
43è²¬ã™ã‚‹ã“と.
44#
45# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
46お
47# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50# の責任を負わない.
51#
52# $Id$
53#++
54
55=begin
56This file includes the processes between semantics analysis and code generation.
57Optimize is one of them.
58Other processes are setting ID for each cell and setting domain information
59
60このファイルには、意味解析からコード生成の間で行うべき処理が含まれる.
61最適化もその一つである.
62その他に、セル毎の ID 付け、ドメインわけを行う.
63コード生成対象となるセルを対象に処理を行うものが含まれる.
64=end
65
66class Namespace
67
68 #=== 各セルに ID (整数値)を割付ける
69 def set_cell_id_and_domain
70 # celltype の各セルに ID を割付ける
71 @celltype_list.each { |t|
72 t.set_cell_id_and_domain
73 }
74
75 # サブネームスペースの各セルに ID を割付ける
76 @namespace_list.each { |n|
77 n.set_cell_id_and_domain
78 }
79 end
80
81 def optimize
82 # celltype の最適化
83 @celltype_list.each { |t|
84 t.optimize
85 }
86
87 # サブネームスペースの最適化
88 @namespace_list.each { |n|
89 n.optimize
90 }
91 end
92
93 def reset_optimize
94 # celltype の最適化
95 @celltype_list.each { |t|
96 t.reset_optimize
97 }
98
99 # サブネームスペースの最適化
100 @namespace_list.each { |n|
101 n.reset_optimize
102 }
103 end
104end
105
106class Celltype
107
108 ID_BASE = 1 # reset_optimize でリセットする
109 @@ID_BASE = ID_BASE
110
111 def set_cell_id_and_domain
112 set_cell_id
113 set_domain
114 end
115
116 #=== 各セルに ID (整数値)を割付ける
117 def set_cell_id
118
119 if $verbose then
120 print( "=== id for the cells of celltype #{get_namespace_path.to_s} ===\n" )
121 end
122
123 if $unique_id then
124 @id_base = @@ID_BASE # id をシステムå…
125¨ä½“で連番にする
126 else
127 @id_base = 1 # base を常に 1 から始める
128 end
129
130 id_specified_cells = []
131 no_id_specified_cells = []
132
133 # プロトタイプを除いた数を求める
134 @cell_list.each{ |c|
135 if c.is_generate? then
136 # c.set_id( @id_base + @n_cell_gen )
137 id = c.get_specified_id
138 if id then
139 id_specified_cells << c
140 else
141 no_id_specified_cells << c
142 end
143
144 # p "#{c.get_name} #{@id_base+@n_cell_gen}"
145 @@ID_BASE += 1
146 @n_cell_gen += 1
147 end
148 }
149
150 @ordered_cell_list = [] # id = 1 が添数 0 に格納される
151 # ID 指定されているセルに id 番号を与える
152 id_specified_cells.each{ |c|
153 id = c.get_specified_id
154 if id > 0 then
155 if id >= @n_cell_gen then
156 cdl_error( "S3001 $1: id too large $2 (max=$3)", c.get_name, id, @n_cell_gen )
157 next
158 end
159 else
160 if - id >= @n_cell_gen then
161 cdl_error( "S3002 $1: id too large $2 (max=$3)", c.get_name, id, @n_cell_gen )
162 next
163 end
164 id = @n_cell_gen + id + 1
165 end
166
167 if @ordered_cell_list[ id - 1 ] then
168 cdl_error( "S3003 $1: id number '$2' conflict with $3", c.get_name, id, @ordered_cell_list[ id - 1 ].get_name )
169 end
170 @ordered_cell_list[ id - 1 ] = c
171 # 通し番号とする場合のため @id_base を加える
172 c.set_id( @id_base - 1 + id )
173 if $verbose then
174 print( "#{c.get_name}: id=#{c.get_id} specified id=#{c.get_specified_id}\n" )
175 end
176 }
177
178 # ID 指定されていないセルに id 番号を与える
179 i = 0
180 no_id_specified_cells.each{ |c|
181 while( @ordered_cell_list[i] != nil )
182 i += 1
183 end
184 @ordered_cell_list[ i ] = c
185 c.set_id( @id_base + i )
186 if $verbose then
187 print( "#{c.get_name}: id=#{c.get_id}\n" )
188 end
189 }
190 if @n_cell_gen >0 && i >= @n_cell_gen then
191 raise "id over id=#{i} N=#{@n_cell_gen}"
192 end
193 end
194
195 def set_domain
196 domain_cells = {}
197 @cell_list.each{ |c|
198 if c.is_generate? then
199 dr = c.get_region.get_domain_root
200 if dr.get_domain_type then
201 dn = dr.get_domain_type.get_name
202 else
203 dn = nil
204 end
205 if @domain_roots[ dn ] then
206 @domain_roots[ dn ] << dr
207 else
208 @domain_roots[ dn ] = [ dr ]
209 end
210 if domain_cells[ dr ] then
211 domain_cells[ dr ] << c
212 else
213 domain_cells[ dr ] = [ c ]
214 end
215 end
216 }
217
218 @domain_roots.each{ |dn, drs|
219 drs.uniq!
220 if $verbose && dn then
221 print "[domain] celltype=#{@name} domainType=#{dn} domainRootRegions={"
222 delim = ""
223 drs.each{ |r|
224 print delim, r.get_name
225 delim = ", "
226 }
227 print "}\n"
228 drs.each{ |r|
229 print "[domain] celltype=#{@name} domainRootRegion=#{r.get_name} domainType=#{dn} domainKind=#{r.get_domain_root.get_domain_type.get_kind} domainCells={"
230 delim = ""
231 domain_cells[r].each{ |c|
232 print delim, c.get_name
233 delim = ", "
234 }
235 print "}\n"
236 }
237 end
238 }
239 if @domain_roots.length > 1 then
240 p @domain_roots
241 raise "ambigous DomainType"
242 end
243
244 @domain_roots.each{ |dn, regions|
245 # domain_type は一つのノードに一つしかないので、一つの要素を無条件で取り出す
246 if regions.length > 1 then
247 if $verbose then
248 cdl_info( "I9999 celltype '$1' has cells in multi-domain.\n", @name )
249 end
250 # if @idx_is_id == false then
251 # cdl_info( "I9999 celltype '$1' forcely set idx_is_id\n", @name )
252 # end
253 @b_need_ptab = true
254 # @idx_is_id_act = true
255 end
256 }
257 end
258
259 def optimize
260
261 # port の参ç…
262§ã™ã‚‹ã‚»ãƒ«ã‚¿ã‚¤ãƒ—の数、セルの数を求める
263 if $verbose then
264 print "=== optimizing celltype #{get_namespace_path.to_s} ===\n"
265 end
266
267 optimize_call
268 if $unopt_entry == false then
269 optimize_entry
270 end
271 end
272
273 #=== Celltype#呼び口最適化
274 def optimize_call
275 @port.each{ |port|
276 next if port.get_port_type != :CALL
277 if port.is_omit? then
278 # 呼び口最適化実施
279 @b_cp_optimized = true
280 @n_call_port_omitted_in_CB += 1 # CB で省略する呼び口
281 port.set_skelton_useless # スケルトン関数不要最適化
282 port.set_VMT_useless # VMT 不要最適化 (直接受け口関数を呼出す)
283 if $verbose then
284 print "optimized by omit: port: #{port.get_name} : o\n"
285 end
286 next
287 elsif port.is_dynamic? then
288 if $verbose then
289 print "unoptimized by dynamic: port: #{port.get_name}\n"
290 end
291 next
292 elsif port.is_ref_desc? then
293 if $verbose then
294 print "unoptimized by ref_desc: port: #{port.get_name}\n"
295 end
296 next
297 end
298
299 if $verbose then
300 print "optimizing port : #{port.get_name}\n"
301 end
302
303 port_cells = [] # 呼びå…
304ˆã‚»ãƒ«
305 port_ports = [] # 呼びå…
306ˆã®ãƒãƒ¼ãƒˆ
307
308 # セルの参ç…
309§ã™ã‚‹ã‚»ãƒ«ã‚’集める(ポートも一緒に集める)
310 @cell_list.each{ |cell|
311
312 if ! cell.is_generate? then
313 next
314 end
315
316 jl = cell.get_join_list
317 j = jl.get_item( port.get_name )
318
319 if j then
320 if j.get_array_member2 then
321 # 呼び口é…
322åˆ—の場合、å…
323¨éƒ¨ã®çµåˆå…
324ˆã‚’集める
325 j.get_array_member2.each { |j2|
326 if j2 then
327 port_cells << j2.get_rhs_cell
328 port_ports << j2.get_rhs_port # 右辺のポート
329 else
330 # optional で、ある添数のみ初期化されていない(すべて初期化されない場合は、下)
331 port_cells << nil
332 port_ports << nil
333 end
334 }
335 else
336 # å…
337¨ã¦ã®çµåˆå…
338ˆã‚’集める
339 port_cells << j.get_rhs_cell
340 port_ports << j.get_rhs_port # 右辺のポート
341 end
342 else
343 # optional で初期化されていない(nil を要素に加えておく)
344 port_cells << nil
345 port_ports << nil # 右辺のポート
346 end
347 }
348
349 # 重複要素を取り除く
350 port_cells.uniq!
351 port_ports.uniq!
352
353 # 呼び口の呼びå…
354ˆãŒä¸€ã¤ã®ãƒãƒ¼ãƒˆã ã‘か?
355 if port_ports.length == 1 then
356
357 # 呼び口é…
358åˆ—が可変長の場合、最適化しない
359 # mikan 呼び口é…
360åˆ—要素数マクロ不å…
361·åˆæš«å®šå¯¾ç­–
362 # より望ましい修正は、受け口へのポインタは省略するが、é…
363åˆ—個数は出力する(#_CP_#, #_TCP_#)
364 # さらにé…
365åˆ—個数が定数化できるのであれば、定数マクロを出力 (#_NCPA_#)
366 next if port.get_array_size == "[]"
367
368 # 呼び口最適化実施
369 @b_cp_optimized = true
370
371 # 呼びå…
372ˆãŒä¸€ã¤ã®ã‚»ãƒ«ã ã‘か?
373 if port_cells.length == 1 then
374
375 # 呼び口は optional で初期化されていない、または受け口はé…
376åˆ—ではないか?
377 if port_ports[0] == nil || port_ports[0].get_array_size == nil then
378
379 @n_call_port_omitted_in_CB += 1 # CB で省略する呼び口
380 port.set_cell_unique # セル一つだけ最適化
381 port.set_skelton_useless # スケルトン関数不要最適化
382 port.set_VMT_useless # VMT 不要最適化 (直接受け口関数を呼出す)
383
384 if $verbose then
385 print "cell_unique, VMT_useless & skelton_useless optimize\n"
386 end
387 else
388 port.set_VMT_useless # VMT 不要最適化 (スケルトン関数を呼出す)
389
390 if $verbose then
391 print "VMT_useless optimize\n"
392 end
393 end
394
395 else # 呼びå…
396ˆãŒè¤‡æ•°ã®ã‚»ãƒ«ï¼ˆå˜ä¸€ã®ãƒãƒ¼ãƒˆï¼‰
397
398 # 呼び口は optional で初期化されていない、または受け口はé…
399åˆ—ではないか?
400 if port_ports[0] == nil || port_ports[0].get_array_size == nil then
401 if ! @singleton then
402 port.set_skelton_useless # スケルトン関数不要最適化
403 port.set_VMT_useless # VMT 不要最適化 (スケルトン関数 or 受け口関数を呼出す)
404
405 if $verbose then
406 print "VMT_useless & skelton useless optimize\n"
407 end
408 else
409 port.set_VMT_useless # VMT 不要最適化 (スケルトン関数 or 受け口関数を呼出す)
410
411 if $verbose then
412 print "VMT_useless optimize\n"
413 end
414 end
415 end
416 end
417
418 port.set_only_callee( port_ports[0], port_cells[0] )
419 # set_cell_unique でない場合 cell は意味がない
420
421 end
422
423 # debug
424 dbgPrint "#{port.get_name} : # of cells : #{port_cells.length} # of ports : #{port_ports.length}\n"
425 }
426 end
427
428 #=== Celltype#受け口最適化
429 # optimize_entry は、呼び口最適化の結果を使用している
430 def optimize_entry
431 # 受け口最適化の設定
432 @port.each{ |port|
433 next if port.get_port_type != :CALL
434
435 # 呼び口側の最適化状æ…
436‹
437 b_VMT_useless = port.is_VMT_useless?
438 b_skelton_useless = port.is_skelton_useless?
439
440 # セルの参ç…
441§ã™ã‚‹ã‚»ãƒ«ã‚’集める(ポートも一緒に集める)
442 @cell_list.each{ |cell|
443
444 if ! cell.is_generate? then
445 next
446 end
447
448 jl = cell.get_join_list
449 j = jl.get_item( port.get_name )
450
451 if j then # optional で結合されていない場合 nil
452 if j.get_array_member2 then
453 # 呼び口é…
454åˆ—
455 j.get_array_member2.each { |j2|
456 if j2 then
457 port2 = j2.get_rhs_port # 右辺のポート
458 # 受け口側の最適化可能性を設定
459 port2.set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless )
460 #else
461 # optional で呼び口é…
462åˆ—要素が初期化されていない
463 end
464 }
465 else
466 port2 = j.get_rhs_port # 右辺のポート
467 # 受け口側の最適化可能性を設定
468 port2.set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless )
469 end
470 end
471 }
472 }
473 end
474
475 #Celltype# リセットする
476 def reset_optimize
477 @@ID_BASE = ID_BASE # 本当は一回だけでよい
478 @id_base = 1 # set_cell_id でリセットされるので不要
479
480 @b_cp_optimized = false # 呼び口最適化
481 @n_call_port_omitted_in_CB = 0 # 呼び口最適化により不生成となったポートの数
482 @n_cell_gen = 0 # 生成セル個数
483 @port.each{ |p|
484 p.reset_optimize
485 }
486 @included_header = {}
487 @domain_roots = {}
488 end
489
490 #Celltype# ヘッダは include されているか
491 #hname::Symbol : ヘッダ名
492 #RETURN:: bool_t: false インクルードされていない、true インクルードされている
493 # #_ISH_#, #_ICT_# でヘッダが取り込まれているかチェックする
494 # false が返った場合、hname は登録されて、次回の呼び出しでは true が返る
495 def header_included?( hname )
496 if @included_header[ hname ] == nil then
497 @included_header[ hname ] = true
498 return false
499 else
500 return true
501 end
502 end
503end
504
505
Note: See TracBrowser for help on using the repository browser.