- Timestamp:
- May 22, 2019, 10:03:37 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/core/optimize.rb
-
Property svn:mime-type
changed from
text/x-ruby
totext/x-ruby;charset=UTF-8
r388 r389 6 6 # Copyright (C) 2008-2018 by TOPPERS Project 7 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 責ãããã¨ï¼ 8 # 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ 9 # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 10 # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. 11 # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 12 # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 13 # スコード中に含まれていること. 14 # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 15 # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 16 # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 17 # の無保証規定を掲載すること. 18 # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 19 # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 20 # と. 21 # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 22 # 作権表示,この利用条件および下記の無保証規定を掲載すること. 23 # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 24 # 報告すること. 25 # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 26 # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 27 # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 28 # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを 29 # 免責すること. 44 30 # 45 # æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è 46 ã 47 # ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç 48 # ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ 49 # ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ害ã«é¢ãã¦ãï¼ã 50 # ã®è²¬ä»»ãè² ããªãï¼ 31 # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 32 # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 33 # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ 34 # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ 35 # の責任を負わない. 51 36 # 52 37 # $Id$ … … 58 43 Other processes are setting ID for each cell and setting domain information 59 44 60 ãã®ãã¡ã¤ã«ã«ã¯ãæå³è§£æããã³ã¼ãçæã®éã§è¡ãã¹ãå¦çãå«ã¾ããï¼ 61 æé©åããã®ä¸ã¤ã§ããï¼ 62 ãã®ä»ã«ãã»ã«æ¯ã® ID ä»ãããã¡ã¤ã³ãããè¡ãï¼ 63 ã³ã¼ãçæ対象ã¨ãªãã»ã«ã対象ã«å¦çãè¡ããã®ãå«ã¾ããï¼ 45 このファイルには、意味解析からコード生成の間で行うべき処理が含まれる. 46 最適化もその一つである. 47 その他に、セル毎の ID 付け、ドメインわけを行う. 48 コード生成対象となるセルを対象に処理を行うものが含まれる. 64 49 =end 65 50 66 51 class Namespace 67 52 68 #=== åã»ã«ã« ID ï¼æ´æ°å¤ï¼ãå²ä»ãã53 #=== 各セルに ID (整数値)を割付ける 69 54 def set_cell_id_and_domain 70 # celltype ã®åã»ã«ã« ID ãå²ä»ãã55 # celltype の各セルに ID を割付ける 71 56 @celltype_list.each { |t| 72 57 t.set_cell_id_and_domain 73 58 } 74 59 75 # ãµããã¼ã ã¹ãã¼ã¹ã®åã»ã«ã« ID ãå²ä»ãã60 # サブネームスペースの各セルに ID を割付ける 76 61 @namespace_list.each { |n| 77 62 n.set_cell_id_and_domain … … 80 65 81 66 def optimize 82 # celltype ã®æé©å67 # celltype の最適化 83 68 @celltype_list.each { |t| 84 69 t.optimize 85 70 } 86 71 87 # ãµããã¼ã ã¹ãã¼ã¹ã®æé©å72 # サブネームスペースの最適化 88 73 @namespace_list.each { |n| 89 74 n.optimize … … 92 77 93 78 def reset_optimize 94 # celltype ã®æé©å79 # celltype の最適化 95 80 @celltype_list.each { |t| 96 81 t.reset_optimize 97 82 } 98 83 99 # ãµããã¼ã ã¹ãã¼ã¹ã®æé©å84 # サブネームスペースの最適化 100 85 @namespace_list.each { |n| 101 86 n.reset_optimize … … 106 91 class Celltype 107 92 108 ID_BASE = 1 # reset_optimize ã§ãªã»ãããã93 ID_BASE = 1 # reset_optimize でリセットする 109 94 @@ID_BASE = ID_BASE 110 95 … … 114 99 end 115 100 116 #=== åã»ã«ã« ID ï¼æ´æ°å¤ï¼ãå²ä»ãã101 #=== 各セルに ID (整数値)を割付ける 117 102 def set_cell_id 118 103 … … 122 107 123 108 if $unique_id then 124 @id_base = @@ID_BASE # id ãã·ã¹ãã å 125 ¨ä½ã§é£çªã«ãã 109 @id_base = @@ID_BASE # id をシステム全体で連番にする 126 110 else 127 @id_base = 1 # base ã常㫠1 ããå§ãã111 @id_base = 1 # base を常に 1 から始める 128 112 end 129 113 … … 131 115 no_id_specified_cells = [] 132 116 133 # ãããã¿ã¤ããé¤ããæ°ãæ±ãã117 # プロトタイプを除いた数を求める 134 118 @cell_list.each{ |c| 135 119 if c.is_generate? then … … 148 132 } 149 133 150 @ordered_cell_list = [] # id = 1 ãæ·»æ° 0 ã«æ ¼ç´ããã151 # ID æå®ããã¦ããã»ã«ã« id çªå·ãä¸ãã134 @ordered_cell_list = [] # id = 1 が添数 0 に格納される 135 # ID 指定されているセルに id 番号を与える 152 136 id_specified_cells.each{ |c| 153 137 id = c.get_specified_id … … 169 153 end 170 154 @ordered_cell_list[ id - 1 ] = c 171 # éãçªå·ã¨ããå ´åã®ãã @id_base ãå ãã155 # 通し番号とする場合のため @id_base を加える 172 156 c.set_id( @id_base - 1 + id ) 173 157 if $verbose then … … 176 160 } 177 161 178 # ID æå®ããã¦ããªãã»ã«ã« id çªå·ãä¸ãã162 # ID 指定されていないセルに id 番号を与える 179 163 i = 0 180 164 no_id_specified_cells.each{ |c| … … 243 227 244 228 @domain_roots.each{ |dn, regions| 245 # domain_type ã¯ä¸ã¤ã®ãã¼ãã«ä¸ã¤ãããªãã®ã§ãä¸ã¤ã®è¦ç´ ãç¡æ¡ä»¶ã§åãåºã229 # domain_type は一つのノードに一つしかないので、一つの要素を無条件で取り出す 246 230 if regions.length > 1 then 247 231 if $verbose then … … 259 243 def optimize 260 244 261 # port ã®åç 262 §ããã»ã«ã¿ã¤ãã®æ°ãã»ã«ã®æ°ãæ±ãã 245 # port の参照するセルタイプの数、セルの数を求める 263 246 if $verbose then 264 247 print "=== optimizing celltype #{get_namespace_path.to_s} ===\n" … … 271 254 end 272 255 273 #=== Celltype# å¼ã³å£æé©å256 #=== Celltype#呼び口最適化 274 257 def optimize_call 275 258 @port.each{ |port| 276 259 next if port.get_port_type != :CALL 277 260 if port.is_omit? then 278 # å¼ã³å£æé©åå®æ½261 # 呼び口最適化実施 279 262 @b_cp_optimized = true 280 @n_call_port_omitted_in_CB += 1 # CB ã§çç¥ããå¼ã³å£281 port.set_skelton_useless # ã¹ã±ã«ãã³é¢æ°ä¸è¦æé©å282 port.set_VMT_useless # VMT ä¸è¦æé©å (ç´æ¥åãå£é¢æ°ãå¼åºã)263 @n_call_port_omitted_in_CB += 1 # CB で省略する呼び口 264 port.set_skelton_useless # スケルトン関数不要最適化 265 port.set_VMT_useless # VMT 不要最適化 (直接受け口関数を呼出す) 283 266 if $verbose then 284 267 print "optimized by omit: port: #{port.get_name} : o\n" … … 301 284 end 302 285 303 port_cells = [] # å¼ã³å 304 ã»ã« 305 port_ports = [] # å¼ã³å 306 ã®ãã¼ã 307 308 # ã»ã«ã®åç 309 §ããã»ã«ãéããï¼ãã¼ããä¸ç·ã«éããï¼ 286 port_cells = [] # 呼び先セル 287 port_ports = [] # 呼び先のポート 288 289 # セルの参照するセルを集める(ポートも一緒に集める) 310 290 @cell_list.each{ |cell| 311 291 … … 319 299 if j then 320 300 if j.get_array_member2 then 321 # å¼ã³å£é 322 åã®å ´åãå 323 ¨é¨ã®çµåå 324 ãéãã 301 # 呼び口配列の場合、全部の結合先を集める 325 302 j.get_array_member2.each { |j2| 326 303 if j2 then 327 304 port_cells << j2.get_rhs_cell 328 port_ports << j2.get_rhs_port # å³è¾ºã®ãã¼ã305 port_ports << j2.get_rhs_port # 右辺のポート 329 306 else 330 # optional ã§ãããæ·»æ°ã®ã¿åæåããã¦ããªãï¼ãã¹ã¦åæåãããªãå ´åã¯ãä¸ï¼307 # optional で、ある添数のみ初期化されていない(すべて初期化されない場合は、下) 331 308 port_cells << nil 332 309 port_ports << nil … … 334 311 } 335 312 else 336 # å 337 ¨ã¦ã®çµåå 338 ãéãã 313 # 全ての結合先を集める 339 314 port_cells << j.get_rhs_cell 340 port_ports << j.get_rhs_port # å³è¾ºã®ãã¼ã315 port_ports << j.get_rhs_port # 右辺のポート 341 316 end 342 317 else 343 # optional ã§åæåããã¦ããªãï¼nil ãè¦ç´ ã«å ãã¦ããï¼318 # optional で初期化されていない(nil を要素に加えておく) 344 319 port_cells << nil 345 port_ports << nil # å³è¾ºã®ãã¼ã320 port_ports << nil # 右辺のポート 346 321 end 347 322 } 348 323 349 # éè¤è¦ç´ ãåãé¤ã324 # 重複要素を取り除く 350 325 port_cells.uniq! 351 326 port_ports.uniq! 352 327 353 # å¼ã³å£ã®å¼ã³å 354 ãä¸ã¤ã®ãã¼ãã ããï¼ 328 # 呼び口の呼び先が一つのポートだけか? 355 329 if port_ports.length == 1 then 356 330 357 # å¼ã³å£é 358 åãå¯å¤é·ã®å ´åãæé©åããªã 359 # mikan å¼ã³å£é 360 åè¦ç´ æ°ãã¯ãä¸å 361 ·åæ«å®å¯¾ç 362 # ããæã¾ããä¿®æ£ã¯ãåãå£ã¸ã®ãã¤ã³ã¿ã¯çç¥ããããé 363 ååæ°ã¯åºåãã(#_CP_#, #_TCP_#) 364 # ããã«é 365 ååæ°ãå®æ°åã§ããã®ã§ããã°ãå®æ°ãã¯ããåºå (#_NCPA_#) 331 # 呼び口配列が可変長の場合、最適化しない 332 # mikan 呼び口配列要素数マクロ不具合暫定対策 333 # より望ましい修正は、受け口へのポインタは省略するが、配列個数は出力する(#_CP_#, #_TCP_#) 334 # さらに配列個数が定数化できるのであれば、定数マクロを出力 (#_NCPA_#) 366 335 next if port.get_array_size == "[]" 367 336 368 # å¼ã³å£æé©åå®æ½337 # 呼び口最適化実施 369 338 @b_cp_optimized = true 370 339 371 # å¼ã³å 372 ãä¸ã¤ã®ã»ã«ã ããï¼ 340 # 呼び先が一つのセルだけか? 373 341 if port_cells.length == 1 then 374 342 375 # å¼ã³å£ã¯ optional ã§åæåããã¦ããªããã¾ãã¯åãå£ã¯é 376 åã§ã¯ãªããï¼ 343 # 呼び口は optional で初期化されていない、または受け口は配列ではないか? 377 344 if port_ports[0] == nil || port_ports[0].get_array_size == nil then 378 345 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 ä¸è¦æé©å (ç´æ¥åãå£é¢æ°ãå¼åºã)346 @n_call_port_omitted_in_CB += 1 # CB で省略する呼び口 347 port.set_cell_unique # セル一つだけ最適化 348 port.set_skelton_useless # スケルトン関数不要最適化 349 port.set_VMT_useless # VMT 不要最適化 (直接受け口関数を呼出す) 383 350 384 351 if $verbose then … … 386 353 end 387 354 else 388 port.set_VMT_useless # VMT ä¸è¦æé©å (ã¹ã±ã«ãã³é¢æ°ãå¼åºã)355 port.set_VMT_useless # VMT 不要最適化 (スケルトン関数を呼出す) 389 356 390 357 if $verbose then … … 393 360 end 394 361 395 else # å¼ã³å 396 ãè¤æ°ã®ã»ã«ï¼åä¸ã®ãã¼ãï¼ 397 398 # å¼ã³å£ã¯ optional ã§åæåããã¦ããªããã¾ãã¯åãå£ã¯é 399 åã§ã¯ãªããï¼ 362 else # 呼び先が複数のセル(単一のポート) 363 364 # 呼び口は optional で初期化されていない、または受け口は配列ではないか? 400 365 if port_ports[0] == nil || port_ports[0].get_array_size == nil then 401 366 if ! @singleton then 402 port.set_skelton_useless # ã¹ã±ã«ãã³é¢æ°ä¸è¦æé©å403 port.set_VMT_useless # VMT ä¸è¦æé©å (ã¹ã±ã«ãã³é¢æ° or åãå£é¢æ°ãå¼åºã)367 port.set_skelton_useless # スケルトン関数不要最適化 368 port.set_VMT_useless # VMT 不要最適化 (スケルトン関数 or 受け口関数を呼出す) 404 369 405 370 if $verbose then … … 407 372 end 408 373 else 409 port.set_VMT_useless # VMT ä¸è¦æé©å (ã¹ã±ã«ãã³é¢æ° or åãå£é¢æ°ãå¼åºã)374 port.set_VMT_useless # VMT 不要最適化 (スケルトン関数 or 受け口関数を呼出す) 410 375 411 376 if $verbose then … … 417 382 418 383 port.set_only_callee( port_ports[0], port_cells[0] ) 419 # set_cell_unique ã§ãªãå ´å cell ã¯æå³ããªã384 # set_cell_unique でない場合 cell は意味がない 420 385 421 386 end … … 426 391 end 427 392 428 #=== Celltype# åãå£æé©å429 # optimize_entry ã¯ãå¼ã³å£æé©åã®çµæã使ç¨ãã¦ãã393 #=== Celltype#受け口最適化 394 # optimize_entry は、呼び口最適化の結果を使用している 430 395 def optimize_entry 431 # åãå£æé©åã®è¨å®396 # 受け口最適化の設定 432 397 @port.each{ |port| 433 398 next if port.get_port_type != :CALL 434 399 435 # å¼ã³å£å´ã®æé©åç¶æ 436 400 # 呼び口側の最適化状態 437 401 b_VMT_useless = port.is_VMT_useless? 438 402 b_skelton_useless = port.is_skelton_useless? 439 403 440 # ã»ã«ã®åç 441 §ããã»ã«ãéããï¼ãã¼ããä¸ç·ã«éããï¼ 404 # セルの参照するセルを集める(ポートも一緒に集める) 442 405 @cell_list.each{ |cell| 443 406 … … 449 412 j = jl.get_item( port.get_name ) 450 413 451 if j then # optional ã§çµåããã¦ããªãå ´ånil414 if j then # optional で結合されていない場合 nil 452 415 if j.get_array_member2 then 453 # å¼ã³å£é 454 å 416 # 呼び口配列 455 417 j.get_array_member2.each { |j2| 456 418 if j2 then 457 port2 = j2.get_rhs_port # å³è¾ºã®ãã¼ã458 # åãå£å´ã®æé©åå¯è½æ§ãè¨å®419 port2 = j2.get_rhs_port # 右辺のポート 420 # 受け口側の最適化可能性を設定 459 421 port2.set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless ) 460 422 #else 461 # optional ã§å¼ã³å£é 462 åè¦ç´ ãåæåããã¦ããªã 423 # optional で呼び口配列要素が初期化されていない 463 424 end 464 425 } 465 426 else 466 port2 = j.get_rhs_port # å³è¾ºã®ãã¼ã467 # åãå£å´ã®æé©åå¯è½æ§ãè¨å®427 port2 = j.get_rhs_port # 右辺のポート 428 # 受け口側の最適化可能性を設定 468 429 port2.set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless ) 469 430 end … … 473 434 end 474 435 475 #Celltype# ãªã»ãããã436 #Celltype# リセットする 476 437 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 # çæã»ã«åæ°438 @@ID_BASE = ID_BASE # 本当は一回だけでよい 439 @id_base = 1 # set_cell_id でリセットされるので不要 440 441 @b_cp_optimized = false # 呼び口最適化 442 @n_call_port_omitted_in_CB = 0 # 呼び口最適化により不生成となったポートの数 443 @n_cell_gen = 0 # 生成セル個数 483 444 @port.each{ |p| 484 445 p.reset_optimize … … 488 449 end 489 450 490 #Celltype# ããã㯠include ããã¦ããã491 #hname::Symbol : ãããå492 #RETURN:: bool_t: false ã¤ã³ã¯ã«ã¼ãããã¦ããªããtrue ã¤ã³ã¯ã«ã¼ãããã¦ãã493 # #_ISH_#, #_ICT_# ã§ããããåãè¾¼ã¾ãã¦ããããã§ãã¯ãã494 # false ãè¿ã£ãå ´åãhname ã¯ç»é²ããã¦ã次åã®å¼ã³åºãã§ã¯ true ãè¿ã451 #Celltype# ヘッダは include されているか 452 #hname::Symbol : ヘッダ名 453 #RETURN:: bool_t: false インクルードされていない、true インクルードされている 454 # #_ISH_#, #_ICT_# でヘッダが取り込まれているかチェックする 455 # false が返った場合、hname は登録されて、次回の呼び出しでは true が返る 495 456 def header_included?( hname ) 496 457 if @included_header[ hname ] == nil then -
Property svn:mime-type
changed from
Note:
See TracChangeset
for help on using the changeset viewer.