Changeset b738974
- Timestamp:
- May 4, 2022, 2:27:25 PM (17 months ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- f6737ae1
- Parents:
- 5695645 (diff), 3b5dcfa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/plot.py
r5695645 rb738974 33 33 "Ops per threads" : Field('Ops' , 0, False), 34 34 "ns per ops/procs" : Field('ns' , 0, False), 35 "Number of threads" : Field(' thrd', 1, False),35 "Number of threads" : Field('' , 1, False), 36 36 "Total Operations(ops)" : Field('Ops' , 0, False), 37 37 "Ops/sec/procs" : Field('Ops' , 0, False), … … 40 40 "Cycle size (# thrds)" : Field('thrd' , 1, False), 41 41 "Duration (ms)" : Field('ms' , 0, False), 42 "Target QPS" : Field('QPS' , 0, False), 43 "Actual QPS" : Field('QPS' , 0, False), 42 "Target QPS" : Field('' , 0, False), 43 "Actual QPS" : Field('' , 0, False), 44 "Average Read Latency" : Field('us' , 0, True), 44 45 "Median Read Latency" : Field('us' , 0, True), 45 46 "Tail Read Latency" : Field('us' , 0, True), 47 "Average Update Latency": Field('us' , 0, True), 46 48 "Median Update Latency" : Field('us' , 0, True), 47 49 "Tail Update Latency" : Field('us' , 0, True), 50 "Update Ratio" : Field('\%' , 0, False), 48 51 } 49 52 … … 92 95 print("Making Plots") 93 96 94 for name, data in s eries.items():97 for name, data in sorted(series.items()): 95 98 _col = next(colors) 96 99 plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x') -
benchmark/process-mutilate.py
r5695645 rb738974 14 14 parser = argparse.ArgumentParser(description='Python Script to convert output from mutilate to rmit like output') 15 15 parser.add_argument('--out', nargs='?', type=argparse.FileType('w'), default=sys.stdout) 16 parser.add_argument('--var', nargs='?', type=str, default='Target QPS') 16 17 try: 17 18 options = parser.parse_args() … … 31 32 32 33 try: 34 latAvs = fields[6] 33 35 lat50s = fields[6] 34 36 lat99s = fields[9] … … 37 39 38 40 try: 41 latAv = locale.atof(latAvs) 39 42 lat50 = locale.atof(lat50s) 40 43 lat99 = locale.atof(lat99s) … … 58 61 try: 59 62 if line.startswith("read"): 60 rlat 50, rlat99 = precentile(line)63 rlatAv, rlat50, rlat99 = precentile(line) 61 64 62 65 elif line.startswith("update"): 63 ulat 50, ulat99 = precentile(line)66 ulatAv, ulat50, ulat99 = precentile(line) 64 67 65 68 elif line.startswith("Total QPS"): … … 84 87 85 88 try: 89 out['Average Read Latency'] = rlatAv 86 90 out['Median Read Latency'] = rlat50 87 91 out['Tail Read Latency'] = rlat99 … … 90 94 91 95 try: 96 out['Average Update Latency'] = ulatAv 92 97 out['Median Update Latency'] = ulat50 93 98 out['Tail Update Latency'] = ulat99 … … 112 117 continue 113 118 114 d = { 'Target QPS': int(rate) }119 d = { options.var : int(rate) } 115 120 116 121 w = extract( f, d ) -
benchmark/readyQ/churn.cfa
r5695645 rb738974 44 44 { 's', "spots", "Number of spots in the system", spot_cnt } 45 45 }; 46 BENCH_OPT_PARSE("cforall c yclebenchmark");46 BENCH_OPT_PARSE("cforall churn benchmark"); 47 47 48 48 { -
benchmark/readyQ/yield.cfa
r5695645 rb738974 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include <limits.h> 5 6 extern "C" { 7 #include <locale.h> 8 #include <getopt.h> 9 } 10 11 #include <unistd.h> 12 13 #include <clock.hfa> 14 #include <time.hfa> 15 #include <stats.hfa> 16 17 #include "../benchcltr.hfa" 18 19 extern bool traceHeapOn(); 20 21 22 volatile bool run = false; 23 volatile unsigned long long global_counter; 1 #include "rq_bench.hfa" 24 2 25 3 thread __attribute__((aligned(128))) Yielder { 26 unsigned long long count er;4 unsigned long long count; 27 5 }; 28 6 void ?{}( Yielder & this ) { 29 this.counter = 0;30 ((thread&)this){ "Yielder Thread", *the_benchmark_cluster };7 ((thread&)this){ "Yielder Thread", bench_cluster }; 8 this.count = 0; 31 9 } 32 10 33 11 void main( Yielder & this ) { 34 12 park(); 35 /* paranoid */ assert( true == __atomic_load_n(&run, __ATOMIC_RELAXED) ); 13 for() { 14 yield(); 15 this.count++; 16 if( clock_mode && stop) break; 17 if(!clock_mode && this.count >= stop_count) break; 18 } 36 19 37 while(__atomic_load_n(&run, __ATOMIC_RELAXED)) { 38 yield(); 39 this.counter++; 40 } 41 __atomic_fetch_add(&global_counter, this.counter, __ATOMIC_SEQ_CST); 20 __atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST); 42 21 } 43 22 44 23 int main(int argc, char * argv[]) { 45 unsigned num_io = 1;46 io_context_params params;47 48 24 cfa_option opt[] = { 49 BENCH_OPT _CFA25 BENCH_OPT 50 26 }; 51 int opt_cnt = sizeof(opt) / sizeof(cfa_option); 52 53 char **left; 54 parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\ncforall yield benchmark", left ); 27 BENCH_OPT_PARSE("cforall yield benchmark"); 55 28 56 29 { 57 printf("Running %d threads on %d processors for %f seconds\n", nthreads, nprocs, duration);30 unsigned long long global_counter = 0; 58 31 59 32 Time start, end; 60 BenchCluster cl = { num_io, params, CFA_STATS_READY_Q};33 BenchCluster bc = { nprocs }; 61 34 { 62 BenchProc procs[nprocs]; 63 { 64 Yielder threads[nthreads]; 65 printf("Starting\n"); 35 threads_left = nthreads; 36 Yielder threads[nthreads]; 37 printf("Starting\n"); 66 38 67 bool is_tty = isatty(STDOUT_FILENO); 68 start = timeHiRes(); 69 run = true; 39 bool is_tty = isatty(STDOUT_FILENO); 40 start = timeHiRes(); 70 41 71 72 73 74 wait(duration, start, end, is_tty);42 for(i; nthreads) { 43 unpark( threads[i] ); 44 } 45 wait(start, is_tty); 75 46 76 run = false; 77 end = timeHiRes(); 78 printf("\nDone\n"); 47 stop = true; 48 end = timeHiRes(); 49 printf("\nDone\n"); 50 51 for(i; nthreads) { 52 Yielder & y = join( threads[i] ); 53 global_counter += y.count; 79 54 } 80 55 } 81 56 82 printf("Duration (ms) : %'ld\n", (end - start)`dms); 83 printf("Number of processors: %'d\n", nprocs); 84 printf("Number of threads : %'d\n", nthreads); 85 printf("Total yields : %'15llu\n", global_counter); 86 printf("Yields per second : %'18.2lf\n", ((double)global_counter) / (end - start)`s); 87 printf("ns per yields : %'18.2lf\n", ((double)(end - start)`ns) / global_counter); 88 printf("Yields per procs : %'15llu\n", global_counter / nprocs); 89 printf("Yields/sec/procs : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`s); 90 printf("ns per yields/procs : %'18.2lf\n", ((double)(end - start)`ns) / (global_counter / nprocs)); 57 printf("Duration (ms) : %'ld\n", (end - start)`dms); 58 printf("Number of processors : %'d\n", nprocs); 59 printf("Number of threads : %'d\n", nthreads); 60 printf("Total Operations(ops): %'15llu\n", global_counter); 61 printf("Ops per second : %'18.2lf\n", ((double)global_counter) / (end - start)`s); 62 printf("ns per ops : %'18.2lf\n", (end - start)`dns / global_counter); 63 printf("Ops per threads : %'15llu\n", global_counter / nthreads); 64 printf("Ops per procs : %'15llu\n", global_counter / nprocs); 65 printf("Ops/sec/procs : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`s); 66 printf("ns per ops/procs : %'18.2lf\n", (end - start)`dns / (global_counter / nprocs)); 91 67 fflush(stdout); 92 68 } -
benchmark/readyQ/yield.cpp
r5695645 rb738974 1 #include <cassert> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <climits> 6 7 extern "C" { 8 #include <locale.h> 9 #include <getopt.h> 10 } 11 12 #include <unistd.h> 13 14 #include <chrono> 15 16 using Clock = std::chrono::high_resolution_clock; 17 using duration_t = std::chrono::duration<double>; 18 using std::chrono::nanoseconds; 19 20 21 template<typename Ratio, typename T> 22 T duration_cast(T seconds) { 23 return std::chrono::duration_cast<std::chrono::duration<T, Ratio>>(std::chrono::duration<T>(seconds)).count(); 24 } 1 #include "rq_bench.hpp" 2 #include <libfibre/fibre.h> 25 3 26 4 volatile bool run = false; 27 5 volatile unsigned long long global_counter; 28 6 29 #include "libfibre/fibre.h"30 7 31 FredBarrier * barrier; 32 struct __attribute__((aligned(128))) counter_t { 33 int value = 0; 34 }; 8 void fibre_main() { 9 fibre_park(); 10 unsigned long long count = 0; 11 for(;;) { 12 Fibre::forceYield(); 13 count++; 14 if( clock_mode && stop) break; 15 if(!clock_mode && count >= stop_count) break; 16 } 35 17 36 void fibre_main( counter_t * counter ) { 37 barrier->wait(); 38 // /* paranoid */ assert( true == __atomic_load_n(&run, __ATOMIC_RELAXED) ); 39 40 while(__atomic_load_n(&run, __ATOMIC_RELAXED)) { 41 Fibre::forceYield(); 42 // fibre_yield(); 43 counter->value++; 44 } 45 __atomic_fetch_add(&global_counter, counter->value, __ATOMIC_SEQ_CST); 18 __atomic_fetch_add(&global_counter, count, __ATOMIC_SEQ_CST); 19 __atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST); 46 20 } 47 21 48 22 int main(int argc, char * argv[]) { 49 double duration = 5; 50 int nprocs = 1; 51 int nthreads = 1; 52 53 std::cout.imbue(std::locale("")); 54 setlocale(LC_ALL, ""); 55 56 for(;;) { 57 static struct option options[] = { 58 {"duration", required_argument, 0, 'd'}, 59 {"nprocs", required_argument, 0, 'p'}, 60 {"nthreads", required_argument, 0, 't'}, 61 {0, 0, 0, 0} 62 }; 63 64 int idx = 0; 65 int opt = getopt_long(argc, argv, "d:p:t:", options, &idx); 66 67 const char * arg = optarg ? optarg : ""; 68 char * end; 69 switch(opt) { 70 case -1: 71 goto run; 72 // Numeric Arguments 73 case 'd': 74 duration = strtod(arg, &end); 75 if(*end != '\0') { 76 fprintf(stderr, "Duration must be a valid double, was %s\n", arg); 77 goto usage; 78 } 79 break; 80 case 't': 81 nthreads = strtoul(arg, &end, 10); 82 if(*end != '\0' || nthreads < 1) { 83 fprintf(stderr, "Number of threads must be a positive integer, was %s\n", arg); 84 goto usage; 85 } 86 break; 87 case 'p': 88 nprocs = strtoul(arg, &end, 10); 89 if(*end != '\0' || nprocs < 1) { 90 fprintf(stderr, "Number of processors must be a positive integer, was %s\n", arg); 91 goto usage; 92 } 93 break; 94 // Other cases 95 default: /* ? */ 96 fprintf( stderr, "Unkown option '%c'\n", opt); 97 usage: 98 fprintf( stderr, "Usage: %s [options]\n", argv[0]); 99 fprintf( stderr, "\n" ); 100 fprintf( stderr, " -d, --duration=DURATION Duration of the experiment, in seconds\n" ); 101 fprintf( stderr, " -t, --nthreads=NTHREADS Number of kernel threads\n" ); 102 fprintf( stderr, " -q, --nqueues=NQUEUES Number of queues per threads\n" ); 103 exit(1); 104 } 105 } 106 run: 23 option_t opt[] = { 24 BENCH_OPT 25 }; 26 BENCH_OPT_PARSE("libfibre yield benchmark"); 107 27 108 28 { 109 29 printf("Running %d threads on %d processors for %lf seconds\n", nthreads, nprocs, duration); 110 30 111 FibreInit( );112 barrier = new FredBarrier(nthreads + 1);31 FibreInit(1, nprocs); 32 uint64_t start, end; 113 33 { 114 Context::CurrCluster().addWorkers(nprocs); 115 { 116 counter_t counters[nthreads]; 117 Fibre threads[nthreads]; 118 for(int i = 0; i < nthreads; i++) { 119 threads[i].run(fibre_main, &counters[i]); 120 } 121 printf("Starting\n"); 122 bool is_tty = isatty(STDOUT_FILENO); 123 auto before = Clock::now(); 124 run = true; 34 threads_left = nthreads; 35 Fibre * threads[nthreads]; 36 for(unsigned i = 0; i < nthreads; i++) { 37 threads[i] = new Fibre( reinterpret_cast<void (*)(void *)>(fibre_main), nullptr ); 38 } 39 printf("Starting\n"); 40 bool is_tty = isatty(STDOUT_FILENO); 41 start = timeHiRes(); 125 42 126 barrier->wait(); 127 for(;;) { 128 usleep(500'000); 129 auto now = Clock::now(); 130 duration_t durr = now - before; 131 if( durr.count() > duration ) { 132 break; 133 } 134 if(is_tty) { 135 std::cout << "\r" << std::setprecision(4) << durr.count(); 136 std::cout.flush(); 137 } 138 } 43 for(unsigned i = 0; i < nthreads; i++ ) { 44 fibre_unpark( threads[i] ); 45 } 46 wait<Fibre>(start, is_tty); 139 47 140 auto after = Clock::now(); 141 duration_t durr = after - before; 142 duration = durr.count(); 143 run = false; 144 printf("\nDone\n"); 145 for(auto & thread : threads) { 146 thread.join(); 147 } 148 149 // for(const auto & counter : counters) { 150 // std::cout << counter.value << std::endl; 151 // } 48 stop = true; 49 end = timeHiRes(); 50 for(unsigned i = 0; i < nthreads; i++ ) { 51 fibre_join( threads[i], nullptr ); 152 52 } 153 53 } 154 54 155 auto dur_nano = duration_cast<std::nano>(duration);156 auto dur_dms = duration_cast<std::milli>(duration);157 158 printf(" Duration (ms) : %'.2lf\n", dur_dms);159 printf(" Total yields : %'15llu\n", global_counter);160 printf(" Yields per procs : %'15llu\n", global_counter / nprocs);161 printf(" Yields per second : %'18.2lf\n", ((double)global_counter) / duration);162 printf(" Yields/sec/procs : %'18.2lf\n", (((double)global_counter) / nprocs) / duration);163 printf(" ns per yields : %'18.2lf\n", dur_nano / global_counter);164 printf("ns per yields/procs : %'18.2lf\n", dur_nano / (global_counter / nprocs));165 55 printf("Duration (ms) : %'ld\n", to_miliseconds(end - start)); 56 printf("Number of processors : %'d\n", nprocs); 57 printf("Number of threads : %'d\n", nthreads); 58 printf("Total Operations(ops): %'15llu\n", global_counter); 59 printf("Ops per second : %'18.2lf\n", ((double)global_counter) / to_fseconds(end - start)); 60 printf("ns per ops : %'18.2lf\n", ((double)(end - start)) / global_counter); 61 printf("Ops per threads : %'15llu\n", global_counter / nthreads); 62 printf("Ops per procs : %'15llu\n", global_counter / nprocs); 63 printf("Ops/sec/procs : %'18.2lf\n", (((double)global_counter) / nprocs) / to_fseconds(end - start)); 64 printf("ns per ops/procs : %'18.2lf\n", ((double)(end - start)) / (global_counter / nprocs)); 65 fflush(stdout); 166 66 } 167 67 } -
benchmark/readyQ/yield.rs
r5695645 rb738974 90 90 }); 91 91 92 println!("Duration (ms) : {}", (duration.as_millis()).to_formatted_string(&Locale::en));93 println!("Number of processors : {}", (nprocs).to_formatted_string(&Locale::en));94 println!("Number of threads : {}", (nthreads).to_formatted_string(&Locale::en));95 println!("Total yields: {:>15}", (global_counter).to_formatted_string(&Locale::en));96 println!(" Yields per second: {:>15}", (((global_counter as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en));97 println!("ns per yields: {:>15}", ((duration.as_nanos() as f64 / global_counter as f64) as u64).to_formatted_string(&Locale::en));98 println!(" Yields per threads: {:>15}", (global_counter / nthreads as u64).to_formatted_string(&Locale::en));99 println!(" Yields per procs: {:>15}", (global_counter / nprocs as u64).to_formatted_string(&Locale::en));100 println!(" Yields/sec/procs: {:>15}", ((((global_counter as f64) / nprocs as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en));101 println!("ns per yields/procs: {:>15}", ((duration.as_nanos() as f64 / (global_counter as f64 / nprocs as f64)) as u64).to_formatted_string(&Locale::en));92 println!("Duration (ms) : {}", (duration.as_millis()).to_formatted_string(&Locale::en)); 93 println!("Number of processors : {}", (nprocs).to_formatted_string(&Locale::en)); 94 println!("Number of threads : {}", (nthreads).to_formatted_string(&Locale::en)); 95 println!("Total Operations(ops): {:>15}", (global_counter).to_formatted_string(&Locale::en)); 96 println!("Ops per second : {:>15}", (((global_counter as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en)); 97 println!("ns per ops : {:>15}", ((duration.as_nanos() as f64 / global_counter as f64) as u64).to_formatted_string(&Locale::en)); 98 println!("Ops per threads : {:>15}", (global_counter / nthreads as u64).to_formatted_string(&Locale::en)); 99 println!("Ops per procs : {:>15}", (global_counter / nprocs as u64).to_formatted_string(&Locale::en)); 100 println!("Ops/sec/procs : {:>15}", ((((global_counter as f64) / nprocs as f64) / duration.as_secs() as f64) as u64).to_formatted_string(&Locale::en)); 101 println!("ns per ops/procs : {:>15}", ((duration.as_nanos() as f64 / (global_counter as f64 / nprocs as f64)) as u64).to_formatted_string(&Locale::en)); 102 102 } -
benchmark/rmit.py
r5695645 rb738974 63 63 return eval(fmt) 64 64 65 # Evaluate all the options 66 # options can be of the for key = val or key = some_math(other_key) 67 # produce a list of all the options to replace some_math(other_key) with actual value 65 68 def eval_options(opts): 69 # Find all the options with dependencies 66 70 dependents = [d for d in opts.values() if type(d) is DependentOpt] 71 72 # we need to find all the straglers 67 73 processed = [] 68 nopts = [] 74 75 # extract all the necessary inputs 76 input_keys = {} 69 77 for d in dependents: 78 # Mark the dependent as seen 70 79 processed.append(d.key) 71 lists = [] 80 81 # process each of the dependencies 72 82 for dvar in d.vars: 83 # Check that it depends on something that exists 73 84 if not dvar in opts.keys(): 74 85 print('ERROR: extra pattern option {}:{} uses unknown key {}'.format(d.key,d.value,dvar), file=sys.stderr) 75 86 sys.exit(1) 76 87 77 lists.append([(dvar, o) for o in opts[dvar]]) 88 # Check that it's not nested 89 if type(dvar) is DependentOpt: 90 print('ERROR: dependent options cannot be nested {}:{} uses key {}'.format(d.key,d.value,dvar), file=sys.stderr) 91 sys.exit(1) 92 93 # Add the values to the input keys 94 if dvar not in input_keys: 95 input_keys[dvar] = opts[dvar] 96 else : 97 if input_keys[dvar] != opts[dvar]: 98 print('INTERNAL ERROR: repeat input do not match {}:{} vs {}'.format(dvar,opts[dvar],input_keys[dvar]), file=sys.stderr) 99 sys.exit(1) 100 101 # Mark the input as seen 78 102 processed.append(dvar) 79 103 80 kopt = [] 81 for vals in list(itertools.product(*lists)): 82 res = ['-{}'.format(d.key), "{}".format(eval_one(d.value, vals))] 83 for k, v in vals: 84 res.extend(['-{}'.format(k), "{}".format(v)]) 85 kopt.append(res) 86 nopts.append(kopt) 87 88 89 for k, vals in opts.items(): 90 if k not in processed: 91 kopt = [] 92 for v in vals: 93 kopt.append(['-{}'.format(k), "{}".format(v)]) 94 nopts.append(kopt) 95 96 return nopts 104 # add in all the straglers they should cause too many problems 105 for k, v in opts.items(): 106 if type(v) is DependentOpt: 107 continue 108 109 if k in processed: 110 # consistency check 111 if k not in input_keys: 112 print('INTERNAL ERROR: key \'{}\' marked as processed but not in input_keys'.format(k), file=sys.stderr) 113 sys.exit(1) 114 continue 115 116 # consistency check 117 if k in input_keys: 118 print('INTERNAL ERROR: key \'{}\' in input_keys but not marked as processed'.format(k), file=sys.stderr) 119 sys.exit(1) 120 121 # add the straggler 122 input_keys[k] = v 123 124 # flatten the dict into a list of pairs so it's easier to work with 125 input_list = [] 126 for k, v in input_keys.items(): 127 input_list.append([(k, o) for o in v]) 128 129 # evaluate all the dependents 130 # they are not allowed to produce new values so it's a one-to-one mapping from here 131 evaluated = [] 132 for inputs in list(itertools.product(*input_list)): 133 this_eval = list(inputs) 134 for d in dependents: 135 this_eval.append((d.key, eval_one(d.value, inputs))) 136 137 evaluated.append(this_eval) 138 139 # reformat everything to a list of arguments 140 formated = [] 141 for o in evaluated: 142 inner = [] 143 for k,v in o: 144 inner.append("-{}".format(k)) 145 inner.append("{}".format(v)) 146 147 # print(inner) 148 formated.append(inner) 149 150 return formated 97 151 98 152 # returns the first option with key 'opt' … … 122 176 known_hosts = { 123 177 "jax": { 124 range( 1, 2 4) : "48-71",125 range( 25, 4 8) : "48-71,144-167",126 range( 49, 9 6) : "48-95,144-191",127 range( 97, 14 4) : "24-95,120-191",128 range(145, 19 2) : "0-95,96-191",178 range( 1, 25) : "48-71", 179 range( 25, 49) : "48-71,144-167", 180 range( 49, 97) : "48-95,144-191", 181 range( 97, 145) : "24-95,120-191", 182 range(145, 193) : "0-95,96-191", 129 183 }, 130 184 } … … 184 238 185 239 except: 186 print('ERROR: invalid arguments', file=sys.stderr)187 parser.print_help(sys.stderr)188 240 sys.exit(1) 189 241 … … 215 267 # Figure out all the combinations to run 216 268 actions = [] 217 for p in itertools.product(range(options.trials), commands, *opts):269 for p in itertools.product(range(options.trials), commands, opts): 218 270 act = [p[1]] 219 271 for o in p[2:]: … … 281 333 282 334 if options.file != sys.stdout: 283 print("Done ");")335 print("Done ") -
src/ControlStruct/MultiLevelExit.cpp
r5695645 rb738974 594 594 } 595 595 596 // check if loop node and if so add else clause if it exists 597 const WhileDoStmt * whilePtr = dynamic_cast<const WhileDoStmt *>(kid.get()); 598 if ( whilePtr && whilePtr->else_) ret.push_back(whilePtr->else_); 599 const ForStmt * forPtr = dynamic_cast<const ForStmt *>(kid.get()); 600 if ( forPtr && forPtr->else_) ret.push_back(forPtr->else_); 601 596 602 if ( ! break_label.empty() ) { 597 603 ret.push_back( labelledNullStmt( ret.back()->location, break_label ) );
Note: See TracChangeset
for help on using the changeset viewer.