├── .gitignore ├── LICENSE ├── README.md ├── SConstruct ├── examples ├── .DS_Store ├── compile.sh ├── config_funarc.json ├── exclude.txt ├── exclude_local.txt ├── final_inputs ├── funarc.c ├── funarc_input_gen.c ├── include.txt ├── include_global.txt └── search_funarc.json ├── logging ├── .svn │ ├── entries │ ├── format │ ├── pristine │ │ ├── 11 │ │ │ └── 11c1139312ec4c92de6db541603e58c776819959.svn-base │ │ ├── 90 │ │ │ └── 902210c34f37a504e2e0a2ad050d685c90c1db46.svn-base │ │ ├── 1a │ │ │ └── 1a4d157a20a6c7a5c303997177cc5e524f08f44e.svn-base │ │ ├── 1c │ │ │ └── 1cd7f40125bfb6c0f62dfdebbe421aacc402a055.svn-base │ │ ├── 2a │ │ │ └── 2ae575fa9ea8f871b8c202fd2f540ef974377aa8.svn-base │ │ ├── 6b │ │ │ └── 6bf0595cc4bfec9a9aa06affc8c5081b910af99e.svn-base │ │ ├── 7b │ │ │ └── 7b65d34bc9fe6c6030d4ea21a22057f13fc37591.svn-base │ │ ├── a1 │ │ │ └── a1cfd5a67a02503a02f3fd0db83da4c971d86bd9.svn-base │ │ ├── ad │ │ │ └── ad83654a245cf6bacc5214da35e9c222796cafa0.svn-base │ │ ├── bf │ │ │ └── bfbadc20c0c89079ad478eea1a2014ce85dbdb11.svn-base │ │ ├── d9 │ │ │ └── d988aec07acc10edc76a55fd2391b5ec6c9633a1.svn-base │ │ └── e2 │ │ │ └── e21757c021c34aef2863f8696549d9460c16e229.svn-base │ └── wc.db ├── cov_checker.c ├── cov_checker.h ├── cov_log.c ├── cov_log.h ├── cov_rand.c ├── cov_rand.h ├── cov_serializer.c ├── cov_serializer.h ├── main.c ├── result ├── spec.cov └── timers.c ├── scripts ├── README ├── brute_force.py ├── clean.sh ├── compile.sh ├── config.sh ├── coverage.sh ├── dd.py ├── dd2.py ├── dd2_notime.py ├── dd_dis.py ├── dd_par.py ├── dependencies.sh ├── find_inputs.py ├── instrument.sh ├── main.py ├── metrics.sh ├── par.py ├── pconfig.sh ├── print_functions.sh ├── proc.py ├── proc.pyc ├── replace_calls.sh ├── run.sh ├── run_configs.py ├── search.sh ├── transform.py ├── transform2.py ├── transform2.pyc ├── transform_notime.py ├── transform_par.py ├── transform_par.pyc ├── utilities.py ├── utilities.pyc └── utilities_par.py └── src ├── AdjustOperators.cpp ├── AdjustOperators.hpp ├── Change.cpp ├── Change.hpp ├── ChangePrecision.cpp ├── ChangePrecision.hpp ├── Coverage.cpp ├── Coverage.hpp ├── CreateCallDependency.cpp ├── CreateCallDependency.hpp ├── CreateConfigFile.cpp ├── CreateConfigFile.hpp ├── CreateIDBitcode.cpp ├── CreateIDBitcode.hpp ├── CreateSearchFile.cpp ├── CreateSearchFile.hpp ├── Debug.hpp ├── FuncStrChange.cpp ├── FuncStrChange.hpp ├── FunctionCalls.cpp ├── FunctionCalls.hpp ├── FunctionChange.cpp ├── FunctionChange.hpp ├── Instrument.cpp ├── Instrument.hpp ├── MeasureMetric.cpp ├── MeasureMetric.hpp ├── Operators.cpp ├── Operators.hpp ├── ParseConfig.cpp ├── ParseConfig.hpp ├── PrintFunctionNames.cpp ├── PrintFunctionNames.hpp ├── PrintVariableNames.cpp ├── PrintVariableNames.hpp ├── RemoveDeadCasting.cpp ├── RemoveDeadCasting.hpp ├── SConscript ├── StrChange.cpp ├── StrChange.hpp ├── Structs.cpp ├── Structs.hpp ├── Transformer.cpp ├── Transformer.hpp ├── Variables.cpp ├── Variables.hpp ├── branches.c ├── config_parser.cpp ├── config_parser.hpp ├── counters.c ├── exclude_coverage.txt ├── exclude_instrument.txt ├── lib └── vjson │ ├── .hgignore │ ├── .svn │ ├── dir-prop-base │ ├── entries │ └── text-base │ │ ├── .hgignore.svn-base │ │ ├── block_allocator.cpp.svn-base │ │ ├── block_allocator.h.svn-base │ │ ├── json.cpp.svn-base │ │ └── json.h.svn-base │ ├── block_allocator.cpp │ ├── block_allocator.h │ ├── json.cpp │ └── json.h └── tests ├── README ├── SConscript ├── bitcode.py ├── bitcode2text.py ├── compare.py ├── compare.sh ├── defaults.conf ├── extract.py ├── pass-builder.py ├── pass.py ├── run.py ├── test1 ├── exclude.txt ├── expected.c ├── include.txt ├── source.c └── source.json ├── test10 ├── exclude.txt ├── expected.c ├── include.txt ├── include_global.txt ├── searchFile.json ├── source.c └── source.json ├── test11 ├── exclude.txt ├── expected.c ├── include.txt ├── include_global.txt ├── source.c └── source.json ├── test2 ├── exclude.txt ├── expected.c ├── include.txt ├── source.c └── source.json ├── test3 ├── exclude.txt ├── expected.c ├── functions.txt ├── include.txt ├── source.c └── source.json ├── test4 ├── exclude.txt ├── expected.c ├── functions.txt ├── include.txt ├── source.c └── source.json ├── test5 ├── exclude.txt ├── expected.c ├── functions.txt ├── include.txt ├── source.c └── source.json ├── test6 ├── exclude.txt ├── expected.c ├── functions.txt ├── include.txt ├── source.c └── source.json ├── test7 ├── exclude.txt ├── expected.c ├── functions.txt ├── include.txt ├── source.c └── source.json ├── test8 ├── exclude.txt ├── expected.c ├── functions.txt ├── include.txt ├── source.c └── source.json ├── test9 ├── exclude.txt ├── expected.c ├── include.txt ├── searchFile.json ├── source.c └── source.json └── tests.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Vim files 2 | .swp 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Compiled Dynamic libraries 11 | *.so 12 | *.dylib 13 | *.dll 14 | 15 | # Compiled Static libraries 16 | *.lai 17 | *.la 18 | *.a 19 | *.lib 20 | 21 | # Executables 22 | *.exe 23 | *.out 24 | *.app 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, UC Berkeley All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the UC Berkeley nor the names of its contributors may 14 | be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY UC BERKELEY ''AS IS'' AND ANY EXPRESS OR IMPLIED 18 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | EVENT SHALL UC BERKELEY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 24 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Precimonious v0.1 2 | 3 | ## Overview 4 | __Precimonious__ employs a _dynamic program analysis_ technique to find a lower 5 | floating-point precision that can be used in any part of a program. 6 | Precimonious performs a search on the program variables trying to lower their 7 | precision subject to accuracy constraints and performance goals. The tool then 8 | recommends a type instantiation for these variables using less precision while 9 | producing an accurate enough answer without causing exceptions. 10 | 11 | This work was presented at the International Conference for High Performance 12 | Computing, Networking, Storage and Analysis (SC'13) in November 2013. 13 | 14 | ## Installation Instruction 15 | ### Requirement 16 | * Scons build system. 17 | * LLVM 3.0. When building LLVM, use --enable-shared flag. 18 | ``` 19 | ../llvm/configure --enable-shared 20 | make 21 | ``` 22 | * Set the following environment variable. 23 | ``` 24 | CORVETTE_PATH=path/to/precimonious 25 | LLVM_COMPILER=clang 26 | LD_LIBRARY_PATH=path/to/llvm/Release/lib 27 | PATH=$PATH:path/to/llvm/Release/bin 28 | ``` 29 | 30 | ### Instruction 31 | After setting up the requirement, you can install Precimonious by 32 | 33 | ``` 34 | cd src 35 | scons -Uc 36 | scons -U 37 | scons -U test // to run the regression test 38 | ``` 39 | 40 | ## Running the Example 41 | * Go inside _examples_ folder, take a look at the file funarc.c. This is the target program that we will tune precision on. 42 | * Compile the program with the following command 43 | ``` 44 | ./compile funarc.c . (remember there is a dot at the end) 45 | ``` 46 | This will create a bitcode file called funarc.bc, together with some other temporary files. 47 | ``` 48 | lli funarc.bc 49 | ``` 50 | This will create a file called spec.cov. This file contains the output and the error threshold in hex format. 51 | * Open funarc.c, comment out the code at line 100, so that the next time the program runs, it will not create the specification file spec.cov again. 52 | ``` 53 | // cov_arr_spec_log("spec.cov", threshold, INPUTS, log) 54 | ``` 55 | * Compile funarc again 56 | ``` 57 | ./compile funarc.c . 58 | ``` 59 | * Now you can run Precimonious to tune precision of funarc using the following command. 60 | ``` 61 | ../scripts/dd2.py funarc.bc search_funarc.json config_funarc.json 62 | ``` 63 | This will create two files: _dd2_diff_funarc.bc.json_ and _dd2_valid_funarc.bc.json_. 64 | 65 | The first file (_dd2_diff_funarc.bc.json_) tells you which variables can be converted to double or float. 66 | 67 | The second file (_dd2_valid_funarc.bc.json_) is the type configuration file in json format. Changing the precision according to the type configuration produces a program that uses less precision and runs faster than the original program. 68 | 69 | You may also wonder what are the other files search_funarc.json and config_funarc.json? 70 | 71 | ``` 72 | search_funarc.json: specify search space for Precimonious. To generate this automatically, run: 73 | ../scripts/search.sh funarc . 74 | config_funarc.json: the type configuration of the original program. To generate this automatically, run: 75 | ../scripts/pconfig.sh funarc . 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /SConstruct: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | from os import access, environ, X_OK 3 | import platform 4 | 5 | #CacheDir('.scons-cache') 6 | Decider('MD5-timestamp') 7 | SetOption('implicit_cache', True) 8 | SourceCode('.', None) 9 | 10 | 11 | ######################################################################## 12 | # 13 | # various command-line options 14 | # 15 | 16 | def pathIsExecutable(key, val, env): 17 | found = env.WhereIs(val) 18 | if found: val = found 19 | PathVariable.PathIsFile(key, val, env) 20 | if not access(val, X_OK): 21 | raise SCons.Errors.UserError('Path for option %s is not executable: %s' % (key, val)) 22 | 23 | opts = Variables(['.scons-options'], ARGUMENTS) 24 | opts.Add(BoolVariable('DEBUG', 'Compile with extra information for debugging', False)) 25 | opts.Add(BoolVariable('OPTIMIZE', 'Compile with optimization', False)) 26 | opts.Add(BoolVariable('NATIVECAML', 'Use the native-code OCaml compiler', True)) 27 | opts.Add(BoolVariable('PROFILE', 'Turn on performance profiling', False)) 28 | opts.Add(BoolVariable('VALGRIND', "Run tests under Valgrinds's memory checker", False)) 29 | opts.Add(PathVariable('LLVM_CONFIG', 'Path to llvm-config executable', WhereIs('llvm-config'), pathIsExecutable)) 30 | 31 | 32 | 33 | 34 | if platform.system() == 'Darwin': 35 | Is64 = False 36 | else: 37 | Is64 = platform.architecture()[0] == '64bit' 38 | 39 | env = Environment( 40 | CCFLAGS = ['-Isrc/lib'], 41 | options=opts, 42 | Is64=Is64, 43 | ) 44 | 45 | env.PrependENVPath('PATH', [ 46 | '/home/rubio/build-llvm/Release/bin', 47 | '/usr/local/bin', 48 | '/opt/local/bin', 49 | '/unsup/ocaml/bin', 50 | '/s/texlive-2008/bin', 51 | '/s/std/bin', 52 | ]) 53 | 54 | 55 | ######################################################################## 56 | # 57 | # basic LaTeX document rendering 58 | # 59 | 60 | env.AppendUnique( 61 | COMMONLATEXFLAGS=['-file-line-error', '-interaction=batchmode'], 62 | LATEXFLAGS='$COMMONLATEXFLAGS', 63 | PDFLATEXFLAGS='$COMMONLATEXFLAGS', 64 | BIBTEXFLAGS='-terse', 65 | ) 66 | 67 | 68 | ######################################################################## 69 | # 70 | # shared compiliation flags 71 | # 72 | 73 | flags = [ 74 | '-Wall', 75 | '-Wformat=2', 76 | '-Wextra', 77 | '-Werror', 78 | '${("", "-g")[DEBUG]}', 79 | '${("", "-O")[OPTIMIZE]}', 80 | ] 81 | 82 | env.AppendUnique( 83 | CCFLAGS=flags, 84 | LINKFLAGS=flags, 85 | ) 86 | 87 | 88 | ######################################################################## 89 | # 90 | # subsidiary scons scripts 91 | # 92 | 93 | SConscript( 94 | dirs=[ 95 | # our stuff 96 | 'src', 97 | ], 98 | exports='env', 99 | ) 100 | -------------------------------------------------------------------------------- /examples/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/examples/.DS_Store -------------------------------------------------------------------------------- /examples/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ################################### 4 | # Shell script to remove output files 5 | # Use: ./compile.sh driver_name . 6 | # #################################### 7 | 8 | loggingPath=$CORVETTE_PATH"/logging" 9 | 10 | clang -emit-llvm -c $2/$1.c -o $2/temp_$1.bc 11 | clang -emit-llvm -c $loggingPath/cov_checker.c -o $2/cov_checker.bc 12 | clang -emit-llvm -c $loggingPath/timers.c -o $2/timers.bc 13 | clang -emit-llvm -c $loggingPath/cov_serializer.c -o $2/cov_serializer.bc 14 | clang -emit-llvm -c $loggingPath/cov_log.c -o $2/cov_log.bc 15 | clang -emit-llvm -c $loggingPath/cov_rand.c -o $2/cov_rand.bc 16 | llvm-link -o $2/$1.bc $2/temp_$1.bc $2/cov_checker.bc $2/cov_serializer.bc $2/cov_log.bc $2/cov_rand.bc $2/timers.bc 17 | 18 | -------------------------------------------------------------------------------- /examples/config_funarc.json: -------------------------------------------------------------------------------- 1 | {"config": [ 2 | {"localVar": { 3 | "function": "fun", 4 | "name": "t1", 5 | "type": "longdouble" 6 | }}, 7 | {"localVar": { 8 | "function": "fun", 9 | "name": "d1", 10 | "type": "longdouble" 11 | }}, 12 | {"localVar": { 13 | "function": "fun", 14 | "name": "x", 15 | "type": "longdouble" 16 | }}, 17 | {"call": { 18 | "id": "24", 19 | "function": "fun", 20 | "name": "sin", 21 | "switch": "sin", 22 | "type": ["double","double"] 23 | }}, 24 | {"localVar": { 25 | "function": "main", 26 | "name": "ans", 27 | "type": "longdouble" 28 | }}, 29 | {"localVar": { 30 | "function": "main", 31 | "name": "s1", 32 | "type": "longdouble" 33 | }}, 34 | {"localVar": { 35 | "function": "main", 36 | "name": "t1", 37 | "type": "longdouble" 38 | }}, 39 | {"localVar": { 40 | "function": "main", 41 | "name": "t2", 42 | "type": "longdouble" 43 | }}, 44 | {"localVar": { 45 | "function": "main", 46 | "name": "h", 47 | "type": "longdouble" 48 | }}, 49 | {"localVar": { 50 | "function": "main", 51 | "name": "dppi", 52 | "type": "longdouble" 53 | }}, 54 | {"call": { 55 | "id": "108", 56 | "function": "main", 57 | "name": "sqrt", 58 | "switch": "sqrt", 59 | "type": ["double","double"] 60 | }} 61 | ]} 62 | -------------------------------------------------------------------------------- /examples/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_rand 2 | cov_rand_sp 3 | cov_log 4 | cov_check 5 | cov_arr_check 6 | cov_serialize 7 | cov_deserialize 8 | cov_spec_log 9 | cov_arr_log 10 | cov_spec_arr_log 11 | current_time_ns 12 | get_time 13 | -------------------------------------------------------------------------------- /examples/exclude_local.txt: -------------------------------------------------------------------------------- 1 | epsilon 2 | threshold 3 | -------------------------------------------------------------------------------- /examples/final_inputs: -------------------------------------------------------------------------------- 1 | 100 2 | 200 3 | 1000 4 | 2000 5 | 10000 6 | 20000 7 | 100000 8 | 200000 9 | 1000000 10 | 2000000 11 | -------------------------------------------------------------------------------- /examples/funarc.c: -------------------------------------------------------------------------------- 1 | #include "../logging/cov_log.h" 2 | #include "../logging/cov_checker.h" 3 | #include "../logging/cov_serializer.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern uint64_t current_time_ns(void); 12 | #define INPUTS 10 13 | 14 | long double fun( long double x ) 15 | { 16 | int k, n = 5; 17 | long double t1, d1 = 1.0L; 18 | 19 | t1 = x; 20 | 21 | for( k = 1; k <= n; k++ ) 22 | { 23 | d1 = 2.0 * d1; 24 | t1 = t1 + sin (d1 * x) / d1; 25 | } 26 | 27 | return t1; 28 | } 29 | 30 | int main() 31 | { 32 | int l; 33 | uint64_t start, end; 34 | long int diff = 0; 35 | 36 | int i, j, k; 37 | long double h, t1, t2, dppi, ans = 5.795776322412856L; 38 | long double s1; 39 | 40 | // variables for logging/checking 41 | long double log[INPUTS]; 42 | long double threshold = 0.0; 43 | long double epsilon = -4.0; 44 | 45 | // 0. read input from the file final_inputs 46 | int finputs[INPUTS]; 47 | 48 | FILE* infile = fopen("final_inputs", "r"); 49 | if (!infile) 50 | { 51 | printf("Could not open final_inputs\n"); 52 | } 53 | 54 | char *s = malloc(10); 55 | for (i = 0; i < INPUTS; i++) 56 | { 57 | if (!feof(infile)) 58 | { 59 | fscanf(infile, "%s", s); 60 | finputs[i] = (int)cov_deserialize(s, 10); 61 | } 62 | } 63 | 64 | 65 | // dummy calls 66 | sqrtf(0); 67 | acosf(0); 68 | sinf(0); 69 | 70 | start = current_time_ns(); 71 | for (l = 0; l < INPUTS; l++) 72 | { 73 | int n = finputs[l]; 74 | t1 = -1.0; 75 | dppi = acos(t1); 76 | s1 = 0.0; 77 | t1 = 0.0; 78 | h = dppi / n; 79 | 80 | for( i = 1; i <= n; i++ ) 81 | { 82 | t2 = fun (i * h); 83 | s1 = s1 + sqrt (h*h + (t2 - t1)*(t2 - t1)); 84 | t1 = t2; 85 | } 86 | 87 | // 1. compute threshold and record result 88 | log[l] = (long double) s1; 89 | if (s1*pow(10, epsilon) > threshold) 90 | { 91 | threshold = s1*pow(10, epsilon); 92 | } 93 | } 94 | end = current_time_ns(); 95 | 96 | diff = (end-start); 97 | 98 | 99 | // 2. create spec, or checking results 100 | cov_arr_spec_log("spec.cov", threshold, INPUTS, log); 101 | cov_arr_log(log, INPUTS, "result", "log.cov"); 102 | cov_check("log.cov", "spec.cov", INPUTS); 103 | 104 | // 3. print score (diff) to a file 105 | FILE* file; 106 | file = fopen("score.cov", "w"); 107 | fprintf(file, "%ld\n", diff); 108 | fclose(file); 109 | 110 | return 0; 111 | 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /examples/funarc_input_gen.c: -------------------------------------------------------------------------------- 1 | #include "../logging/cov_log.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | long double fun( long double x ) 10 | { 11 | int k, n = 5; 12 | long double t1, d1 = 1.0L; 13 | 14 | t1 = x; 15 | 16 | for( k = 1; k <= n; k++ ) 17 | { 18 | d1 = 2.0 * d1; 19 | t1 = t1 + sin (d1 * x) / d1; 20 | } 21 | 22 | return t1; 23 | } 24 | 25 | int main() 26 | { 27 | // input n is randomly generated 28 | srand(time(NULL)); 29 | int n = (rand()+1)%100000; 30 | 31 | int i, j, k; 32 | long double h, t1, t2, dppi, ans = 5.795776322412856L; 33 | long double s1; 34 | 35 | // dummy calls 36 | sqrtf(0); 37 | acosf(0); 38 | sinf(0); 39 | 40 | t1 = -1.0; 41 | dppi = acos(t1); 42 | s1 = 0.0; 43 | t1 = 0.0; 44 | h = dppi / n; 45 | 46 | for( i = 1; i <= n; i++ ) 47 | { 48 | t2 = fun (i * h); 49 | s1 = s1 + sqrt (h*h + (t2 - t1)*(t2 - t1)); 50 | t1 = t2; 51 | } 52 | 53 | // write randomly generated input to file 'inputs' 54 | // write in form of binary format using cov_log 55 | cov_log("result", "inputs", 1, (long double)n); 56 | 57 | return 0; 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /examples/include.txt: -------------------------------------------------------------------------------- 1 | cov_check 2 | cov_deserialize 3 | cov_log 4 | cov_serialize 5 | current_time_ns 6 | fun 7 | get_time 8 | main 9 | -------------------------------------------------------------------------------- /examples/include_global.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/examples/include_global.txt -------------------------------------------------------------------------------- /examples/search_funarc.json: -------------------------------------------------------------------------------- 1 | {"config": [ 2 | {"localVar": { 3 | "function": "fun", 4 | "name": "t1", 5 | "type": ["float", "double", "longdouble"] 6 | }}, 7 | {"localVar": { 8 | "function": "fun", 9 | "name": "d1", 10 | "type": ["float", "double", "longdouble"] 11 | }}, 12 | {"localVar": { 13 | "function": "fun", 14 | "name": "x", 15 | "type": ["float", "double", "longdouble"] 16 | }}, 17 | {"call": { 18 | "id": "24", 19 | "function": "fun", 20 | "name": "sin", 21 | "switch": ["sinf","sin"], 22 | "type": [["float","float"], ["double","double"]] 23 | }}, 24 | {"localVar": { 25 | "function": "main", 26 | "name": "ans", 27 | "type": ["float", "double", "longdouble"] 28 | }}, 29 | {"localVar": { 30 | "function": "main", 31 | "name": "s1", 32 | "type": ["float", "double", "longdouble"] 33 | }}, 34 | {"localVar": { 35 | "function": "main", 36 | "name": "t1", 37 | "type": ["float", "double", "longdouble"] 38 | }}, 39 | {"localVar": { 40 | "function": "main", 41 | "name": "t2", 42 | "type": ["float", "double", "longdouble"] 43 | }}, 44 | {"localVar": { 45 | "function": "main", 46 | "name": "h", 47 | "type": ["float", "double", "longdouble"] 48 | }}, 49 | {"localVar": { 50 | "function": "main", 51 | "name": "dppi", 52 | "type": ["float", "double", "longdouble"] 53 | }}, 54 | {"call": { 55 | "id": "108", 56 | "function": "main", 57 | "name": "sqrt", 58 | "switch": ["sqrtf","sqrt"], 59 | "type": [["float","float"], ["double","double"]] 60 | }} 61 | ]} 62 | -------------------------------------------------------------------------------- /logging/.svn/entries: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /logging/.svn/format: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /logging/.svn/pristine/11/11c1139312ec4c92de6db541603e58c776819959.svn-base: -------------------------------------------------------------------------------- 1 | #ifndef RAND_H_INCLUDED 2 | #define RAND_H_INCLUDED 3 | 4 | double cov_rand(int min_e, int max_e); 5 | 6 | double cov_rand_sp(int itv); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /logging/.svn/pristine/1a/1a4d157a20a6c7a5c303997177cc5e524f08f44e.svn-base: -------------------------------------------------------------------------------- 1 | result=1.230000000000000e-01 2 | result=[0.0, 0.1, 0.3] 3 | tolerance=0.0 4 | -------------------------------------------------------------------------------- /logging/.svn/pristine/1c/1cd7f40125bfb6c0f62dfdebbe421aacc402a055.svn-base: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H_INCLUDED 2 | #define LOG_H_INCLUDED 3 | 4 | #include 5 | 6 | void cov_log(char*, char*, int, ...); 7 | void cov_log_(int*, ...); 8 | void cov_spec_log(char*, long double, int, ...); 9 | void cov_spec_log_(long double*, int*, ...); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_arr_log_(long double**, int*); 12 | void cov_arr_spec_log(char*, long double, int, long double*); 13 | void cov_arr_spec_log_(long double*, int*, long double**); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /logging/.svn/pristine/2a/2ae575fa9ea8f871b8c202fd2f540ef974377aa8.svn-base: -------------------------------------------------------------------------------- 1 | #ideal 2 | CDCCCCCCCCCCCCCCFB3F CDCCCCCCCCCCCCCCFC3F 3 | #delta 4 | 00000000000000000000 5 | -------------------------------------------------------------------------------- /logging/.svn/pristine/6b/6bf0595cc4bfec9a9aa06affc8c5081b910af99e.svn-base: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cov_serializer.h" 3 | 4 | void cov_serialize(long double f, unsigned char* buf, int length) { 5 | int i; 6 | union { 7 | unsigned char bytes[10]; 8 | long double val; 9 | } bfconvert; 10 | 11 | bfconvert.val = f; 12 | 13 | for (i = 0; i < length; i++) { 14 | buf[i] = bfconvert.bytes[i]; 15 | } 16 | } 17 | 18 | long double cov_deserialize(char* buf, int length) { 19 | int i; 20 | unsigned int u; 21 | union { 22 | unsigned char bytes[10]; 23 | long double val; 24 | } bfconvert; 25 | 26 | for (i = 0; i < length; i++) { 27 | sscanf(buf, "%02X", &u); 28 | bfconvert.bytes[i] = u; 29 | buf += 2; 30 | } 31 | 32 | return bfconvert.val; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /logging/.svn/pristine/90/902210c34f37a504e2e0a2ad050d685c90c1db46.svn-base: -------------------------------------------------------------------------------- 1 | #include "cov_log.h" 2 | #include "cov_checker.h" 3 | 4 | int main(int argc, char*argv[]) { 5 | long double arr[3]; 6 | arr[0] = 0.123451243534534; 7 | arr[1] = 0.235341232353411; 8 | arr[2] = 0.398885094850490; 9 | // cov_log("ideal", "spec.cov", 2, 0.1L, 0.2L); 10 | // cov_log("delta", "spec.cov", 1, 0.0L); 11 | // cov_spec_log(0.1, 0, "spec.cov"); 12 | // cov_log(argv[0], "log.cov", 2, 0.1L, 0.2L); 13 | cov_check("log.cov", "spec.cov", 2); 14 | // cov_arr_log(arr, 3, argv[0], "log.cov"); 15 | // cov_arr_check("log.cov", "spec.cov", 3); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /logging/.svn/pristine/a1/a1cfd5a67a02503a02f3fd0db83da4c971d86bd9.svn-base: -------------------------------------------------------------------------------- 1 | #ifndef CHECKER_H_INCLUDED 2 | #define CHECKER_H_INCLUDED 3 | 4 | void cov_check(char*, char*, int); 5 | void cov_check_(int*); 6 | void cov_check_par(char*, char*, int, char*); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /logging/.svn/pristine/ad/ad83654a245cf6bacc5214da35e9c222796cafa0.svn-base: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "cov_log.h" 6 | #include "cov_serializer.h" 7 | 8 | void cov_log(char* msg, char* fn, int count, ...) 9 | { 10 | FILE* file; 11 | file = fopen(fn, "a"); 12 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 13 | 14 | va_list ap; 15 | int i, j; 16 | va_start(ap, count); 17 | for (j=0; j < count; j++) 18 | { 19 | int ld_size; 20 | unsigned char* buf; 21 | long double ld; 22 | 23 | ld = va_arg(ap, long double); 24 | ld_size = 10; 25 | buf = malloc(ld_size); 26 | cov_serialize(ld, buf, ld_size); 27 | for (i = 0; i < ld_size; i++) 28 | { 29 | fprintf(file, "%02X", buf[i]); 30 | } 31 | fprintf(file, " "); 32 | } 33 | va_end(ap); 34 | fprintf(file, "\n"); 35 | fclose(file); 36 | } 37 | 38 | void cov_log_(int* count_pointer, ...) 39 | { 40 | FILE* file; 41 | file = fopen("log.cov", "a"); 42 | fprintf(file, "#result\n"); 43 | int count = *count_pointer; 44 | 45 | va_list ap; 46 | int i, j; 47 | va_start(ap, count); 48 | for (j=0; j < count; j++) 49 | { 50 | int ld_size; 51 | unsigned char* buf; 52 | long double* ld; 53 | 54 | ld = va_arg(ap, long double*); 55 | ld_size = 10; 56 | buf = malloc(ld_size); 57 | cov_serialize(*ld, buf, ld_size); 58 | for (i = 0; i < ld_size; i++) 59 | { 60 | fprintf(file, "%02X", buf[i]); 61 | } 62 | fprintf(file, " "); 63 | } 64 | va_end(ap); 65 | fprintf(file, "\n"); 66 | fclose(file); 67 | } 68 | 69 | void cov_spec_log(char* fn, long double delta, int count, ...) 70 | { 71 | // 72 | // logging ideal value 73 | // 74 | FILE* file; 75 | file = fopen(fn, "a"); 76 | fprintf(file, "#ideal\n"); 77 | 78 | va_list ap; 79 | int i, j; 80 | va_start(ap, count); 81 | for (j=0; j < count; j++) 82 | { 83 | int ld_size; 84 | unsigned char* buf; 85 | long double ld; 86 | 87 | ld = va_arg(ap, long double); 88 | ld_size = 10; 89 | buf = malloc(ld_size); 90 | cov_serialize(ld, buf, ld_size); 91 | for (i = 0; i < ld_size; i++) 92 | { 93 | fprintf(file, "%02X", buf[i]); 94 | } 95 | fprintf(file, " "); 96 | } 97 | va_end(ap); 98 | fprintf(file, "\n"); 99 | fclose(file); 100 | 101 | // 102 | // logging delta 103 | // 104 | cov_log("delta", fn, 1, delta); 105 | } 106 | 107 | void cov_spec_log_(long double* delta_pointer, int* count_pointer, ...) 108 | { 109 | long double delta = *delta_pointer; 110 | int count = *count_pointer; 111 | 112 | // 113 | // logging ideal value 114 | // 115 | FILE* file; 116 | file = fopen("spec.cov", "a"); 117 | fprintf(file, "#ideal\n"); 118 | 119 | va_list ap; 120 | int i, j; 121 | va_start(ap, count); 122 | for (j=0; j < count; j++) 123 | { 124 | int ld_size; 125 | unsigned char* buf; 126 | long double* ld; 127 | 128 | ld = va_arg(ap, long double*); 129 | ld_size = 10; 130 | buf = malloc(ld_size); 131 | cov_serialize(*ld, buf, ld_size); 132 | for (i = 0; i < ld_size; i++) 133 | { 134 | fprintf(file, "%02X", buf[i]); 135 | } 136 | fprintf(file, " "); 137 | } 138 | va_end(ap); 139 | fprintf(file, "\n"); 140 | fclose(file); 141 | 142 | // 143 | // logging delta 144 | // 145 | cov_log("delta", "spec.cov", 1, delta); 146 | } 147 | 148 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) 149 | { 150 | int ld_size, i, j; 151 | unsigned char* buf; 152 | FILE *file; 153 | 154 | file = fopen(fn, "a"); 155 | ld_size = 10; 156 | buf = malloc(ld_size); 157 | 158 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 159 | for (i = 0; i < size; i++) { 160 | long double ld = lds[i]; 161 | cov_serialize(ld, buf, ld_size); 162 | if (i > 0) fprintf(file, " "); 163 | for (j = 0; j < ld_size; j++) { 164 | fprintf(file, "%02X", buf[j]); 165 | } 166 | } 167 | fprintf(file, "\n"); 168 | fclose(file); 169 | } 170 | 171 | void cov_arr_log_(long double** lds_pointer, int* size_pointer) 172 | { 173 | int ld_size, i, j; 174 | unsigned char* buf; 175 | FILE *file; 176 | 177 | file = fopen("spec.cov", "a"); 178 | ld_size = 10; 179 | buf = malloc(ld_size); 180 | 181 | fprintf(file, "#result\n"); 182 | long double* lds = *lds_pointer; 183 | int size = *size_pointer; 184 | for (i = 0; i < size; i++) { 185 | long double ld = lds[i]; 186 | cov_serialize(ld, buf, ld_size); 187 | if (i > 0) fprintf(file, " "); 188 | for (j = 0; j < ld_size; j++) { 189 | fprintf(file, "%02X", buf[j]); 190 | } 191 | } 192 | fprintf(file, "\n"); 193 | fclose(file); 194 | } 195 | 196 | void cov_arr_spec_log(char* fn, long double delta, int count, long double* lds) 197 | { 198 | // 199 | // logging ideal value 200 | // 201 | cov_arr_log(lds, count, "ideal", fn); 202 | 203 | // 204 | // logging delta value 205 | // 206 | cov_log("delta", fn, 1, delta); 207 | } 208 | 209 | void cov_arr_spec_log_(long double* delta, int* count, long double** lds) 210 | { 211 | // 212 | // logging ideal value 213 | // 214 | cov_arr_log(*lds, *count, "ideal", "spec.cov"); 215 | 216 | // 217 | // logging delta value 218 | // 219 | cov_log("delta", "spec.cov", 1, *delta); 220 | } 221 | -------------------------------------------------------------------------------- /logging/.svn/pristine/bf/bfbadc20c0c89079ad478eea1a2014ce85dbdb11.svn-base: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "cov_rand.h" 4 | 5 | double cov_rand(int min_e, int max_e) 6 | { 7 | double mantisa = (double)rand() / ((double)RAND_MAX+1.0); 8 | double e = rand()%(max_e-min_e) + min_e; // [min_e, max_e-1] 9 | double rand = (1.0 + mantisa) * pow(2.0, e); 10 | 11 | return rand; 12 | } 13 | 14 | double cov_rand_sp(int itv) 15 | { 16 | switch (itv) { 17 | case 0: 18 | return -1.0* cov_rand(64, 127); 19 | case 1: 20 | return -1.0* cov_rand(0, 64); 21 | case 2: 22 | return -1.0* cov_rand(-63, 0); 23 | case 3: 24 | return -1.0* cov_rand(-126, -63); 25 | case 4: 26 | return 1.0*0.0; 27 | case 5: 28 | return -1.0*0.0; 29 | case 6: 30 | return cov_rand(-126, -63); 31 | case 7: 32 | return cov_rand(-63, 0); 33 | case 8: 34 | return cov_rand(0, 64); 35 | case 9: 36 | return cov_rand(64, 127); 37 | default: 38 | return cov_rand_sp(itv%10); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /logging/.svn/pristine/d9/d988aec07acc10edc76a55fd2391b5ec6c9633a1.svn-base: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZER_H_INCLUDED 2 | #define SERIALIZER_H_INCLUDED 3 | void cov_serialize(long double, unsigned char*, int); 4 | long double cov_deserialize(char*, int); 5 | #endif 6 | -------------------------------------------------------------------------------- /logging/.svn/pristine/e2/e21757c021c34aef2863f8696549d9460c16e229.svn-base: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | 15 | #if defined(__i386__) 16 | 17 | uint64_t rdtsc(void) 18 | { 19 | uint64_t x; 20 | __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); 21 | return x; 22 | } 23 | #elif defined(__x86_64__) 24 | 25 | uint64_t rdtsc(void) 26 | { 27 | unsigned hi, lo; 28 | __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 29 | return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 ); 30 | } 31 | 32 | #elif defined(__powerpc__) 33 | 34 | uint64_t rdtsc(void) 35 | { 36 | uint64_t result=0; 37 | unsigned long upper, lower,tmp; 38 | __asm__ volatile( 39 | "0: \n" 40 | "\tmftbu %0 \n" 41 | "\tmftb %1 \n" 42 | "\tmftbu %2 \n" 43 | "\tcmpw %2,%0 \n" 44 | "\tbne 0b \n" 45 | : "=r"(upper),"=r"(lower),"=r"(tmp) 46 | ); 47 | result = upper; 48 | result = result<<32; 49 | result = result|lower; 50 | 51 | return(result); 52 | } 53 | #else 54 | 55 | #error "No tick counter is available!" 56 | 57 | #endif 58 | 59 | #define MONTONIC_TIME 1 60 | 61 | static void get_time(struct timespec *ts) 62 | { 63 | #if MONTONIC_TIME 64 | int clock_type = CLOCK_MONOTONIC; 65 | #else 66 | int clock_type = CLOCK_REALTIME; 67 | #endif 68 | if (syscall(__NR_clock_gettime, clock_type, ts)) { 69 | printf("clock_gettime(MONOTONIC/REALTIME) failed"); 70 | exit(-1); 71 | } 72 | } 73 | 74 | 75 | uint64_t current_time_ns(void) 76 | { 77 | struct timespec ts; 78 | get_time(&ts); 79 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 80 | } 81 | uint64_t current_time_us(void) 82 | { 83 | struct timespec ts; 84 | get_time(&ts); 85 | return ts.tv_sec * 1000000ULL + ts.tv_nsec/1000; 86 | } 87 | unsigned current_time_sec(void) 88 | { 89 | struct timespec ts; 90 | get_time(&ts); 91 | return ts.tv_sec; 92 | } 93 | -------------------------------------------------------------------------------- /logging/.svn/wc.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/logging/.svn/wc.db -------------------------------------------------------------------------------- /logging/cov_checker.h: -------------------------------------------------------------------------------- 1 | #ifndef CHECKER_H_INCLUDED 2 | #define CHECKER_H_INCLUDED 3 | 4 | void cov_check(char*, char*, int); 5 | void cov_check_(int*); 6 | void cov_check_par(char*, char*, int, char*); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /logging/cov_log.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "cov_log.h" 6 | #include "cov_serializer.h" 7 | 8 | void cov_log(char* msg, char* fn, int count, ...) 9 | { 10 | FILE* file; 11 | file = fopen(fn, "a"); 12 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 13 | 14 | va_list ap; 15 | int i, j; 16 | va_start(ap, count); 17 | for (j=0; j < count; j++) 18 | { 19 | int ld_size; 20 | unsigned char* buf; 21 | long double ld; 22 | 23 | ld = va_arg(ap, long double); 24 | ld_size = 10; 25 | buf = malloc(ld_size); 26 | cov_serialize(ld, buf, ld_size); 27 | for (i = 0; i < ld_size; i++) 28 | { 29 | fprintf(file, "%02X", buf[i]); 30 | } 31 | fprintf(file, " "); 32 | } 33 | va_end(ap); 34 | fprintf(file, "\n"); 35 | fclose(file); 36 | } 37 | 38 | void cov_log_(int* count_pointer, ...) 39 | { 40 | FILE* file; 41 | file = fopen("log.cov", "a"); 42 | fprintf(file, "#result\n"); 43 | int count = *count_pointer; 44 | 45 | va_list ap; 46 | int i, j; 47 | va_start(ap, count); 48 | for (j=0; j < count; j++) 49 | { 50 | int ld_size; 51 | unsigned char* buf; 52 | long double* ld; 53 | 54 | ld = va_arg(ap, long double*); 55 | ld_size = 10; 56 | buf = malloc(ld_size); 57 | cov_serialize(*ld, buf, ld_size); 58 | for (i = 0; i < ld_size; i++) 59 | { 60 | fprintf(file, "%02X", buf[i]); 61 | } 62 | fprintf(file, " "); 63 | } 64 | va_end(ap); 65 | fprintf(file, "\n"); 66 | fclose(file); 67 | } 68 | 69 | void cov_spec_log(char* fn, long double delta, int count, ...) 70 | { 71 | // 72 | // logging ideal value 73 | // 74 | FILE* file; 75 | file = fopen(fn, "a"); 76 | fprintf(file, "#ideal\n"); 77 | 78 | va_list ap; 79 | int i, j; 80 | va_start(ap, count); 81 | for (j=0; j < count; j++) 82 | { 83 | int ld_size; 84 | unsigned char* buf; 85 | long double ld; 86 | 87 | ld = va_arg(ap, long double); 88 | ld_size = 10; 89 | buf = malloc(ld_size); 90 | cov_serialize(ld, buf, ld_size); 91 | for (i = 0; i < ld_size; i++) 92 | { 93 | fprintf(file, "%02X", buf[i]); 94 | } 95 | fprintf(file, " "); 96 | } 97 | va_end(ap); 98 | fprintf(file, "\n"); 99 | fclose(file); 100 | 101 | // 102 | // logging delta 103 | // 104 | cov_log("delta", fn, 1, delta); 105 | } 106 | 107 | void cov_spec_log_(long double* delta_pointer, int* count_pointer, ...) 108 | { 109 | long double delta = *delta_pointer; 110 | int count = *count_pointer; 111 | 112 | // 113 | // logging ideal value 114 | // 115 | FILE* file; 116 | file = fopen("spec.cov", "a"); 117 | fprintf(file, "#ideal\n"); 118 | 119 | va_list ap; 120 | int i, j; 121 | va_start(ap, count); 122 | for (j=0; j < count; j++) 123 | { 124 | int ld_size; 125 | unsigned char* buf; 126 | long double* ld; 127 | 128 | ld = va_arg(ap, long double*); 129 | ld_size = 10; 130 | buf = malloc(ld_size); 131 | cov_serialize(*ld, buf, ld_size); 132 | for (i = 0; i < ld_size; i++) 133 | { 134 | fprintf(file, "%02X", buf[i]); 135 | } 136 | fprintf(file, " "); 137 | } 138 | va_end(ap); 139 | fprintf(file, "\n"); 140 | fclose(file); 141 | 142 | // 143 | // logging delta 144 | // 145 | cov_log("delta", "spec.cov", 1, delta); 146 | } 147 | 148 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) 149 | { 150 | int ld_size, i, j; 151 | unsigned char* buf; 152 | FILE *file; 153 | 154 | file = fopen(fn, "a"); 155 | ld_size = 10; 156 | buf = malloc(ld_size); 157 | 158 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 159 | for (i = 0; i < size; i++) { 160 | long double ld = lds[i]; 161 | cov_serialize(ld, buf, ld_size); 162 | if (i > 0) fprintf(file, " "); 163 | for (j = 0; j < ld_size; j++) { 164 | fprintf(file, "%02X", buf[j]); 165 | } 166 | } 167 | fprintf(file, "\n"); 168 | fclose(file); 169 | } 170 | 171 | void cov_arr_log_(long double** lds_pointer, int* size_pointer) 172 | { 173 | int ld_size, i, j; 174 | unsigned char* buf; 175 | FILE *file; 176 | 177 | file = fopen("spec.cov", "a"); 178 | ld_size = 10; 179 | buf = malloc(ld_size); 180 | 181 | fprintf(file, "#result\n"); 182 | long double* lds = *lds_pointer; 183 | int size = *size_pointer; 184 | for (i = 0; i < size; i++) { 185 | long double ld = lds[i]; 186 | cov_serialize(ld, buf, ld_size); 187 | if (i > 0) fprintf(file, " "); 188 | for (j = 0; j < ld_size; j++) { 189 | fprintf(file, "%02X", buf[j]); 190 | } 191 | } 192 | fprintf(file, "\n"); 193 | fclose(file); 194 | } 195 | 196 | void cov_arr_spec_log(char* fn, long double delta, int count, long double* lds) 197 | { 198 | // 199 | // logging ideal value 200 | // 201 | cov_arr_log(lds, count, "ideal", fn); 202 | 203 | // 204 | // logging delta value 205 | // 206 | cov_log("delta", fn, 1, delta); 207 | } 208 | 209 | void cov_arr_spec_log_(long double* delta, int* count, long double** lds) 210 | { 211 | // 212 | // logging ideal value 213 | // 214 | cov_arr_log(*lds, *count, "ideal", "spec.cov"); 215 | 216 | // 217 | // logging delta value 218 | // 219 | cov_log("delta", "spec.cov", 1, *delta); 220 | } 221 | -------------------------------------------------------------------------------- /logging/cov_log.h: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H_INCLUDED 2 | #define LOG_H_INCLUDED 3 | 4 | #include 5 | 6 | void cov_log(char*, char*, int, ...); 7 | void cov_log_(int*, ...); 8 | void cov_spec_log(char*, long double, int, ...); 9 | void cov_spec_log_(long double*, int*, ...); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_arr_log_(long double**, int*); 12 | void cov_arr_spec_log(char*, long double, int, long double*); 13 | void cov_arr_spec_log_(long double*, int*, long double**); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /logging/cov_rand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "cov_rand.h" 4 | 5 | double cov_rand(int min_e, int max_e) 6 | { 7 | double mantisa = (double)rand() / ((double)RAND_MAX+1.0); 8 | double e = rand()%(max_e-min_e) + min_e; // [min_e, max_e-1] 9 | double rand = (1.0 + mantisa) * pow(2.0, e); 10 | 11 | return rand; 12 | } 13 | 14 | double cov_rand_sp(int itv) 15 | { 16 | switch (itv) { 17 | case 0: 18 | return -1.0* cov_rand(64, 127); 19 | case 1: 20 | return -1.0* cov_rand(0, 64); 21 | case 2: 22 | return -1.0* cov_rand(-63, 0); 23 | case 3: 24 | return -1.0* cov_rand(-126, -63); 25 | case 4: 26 | return 1.0*0.0; 27 | case 5: 28 | return -1.0*0.0; 29 | case 6: 30 | return cov_rand(-126, -63); 31 | case 7: 32 | return cov_rand(-63, 0); 33 | case 8: 34 | return cov_rand(0, 64); 35 | case 9: 36 | return cov_rand(64, 127); 37 | default: 38 | return cov_rand_sp(itv%10); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /logging/cov_rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_H_INCLUDED 2 | #define RAND_H_INCLUDED 3 | 4 | double cov_rand(int min_e, int max_e); 5 | 6 | double cov_rand_sp(int itv); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /logging/cov_serializer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cov_serializer.h" 3 | 4 | void cov_serialize(long double f, unsigned char* buf, int length) { 5 | int i; 6 | union { 7 | unsigned char bytes[10]; 8 | long double val; 9 | } bfconvert; 10 | 11 | bfconvert.val = f; 12 | 13 | for (i = 0; i < length; i++) { 14 | buf[i] = bfconvert.bytes[i]; 15 | } 16 | } 17 | 18 | long double cov_deserialize(char* buf, int length) { 19 | int i; 20 | unsigned int u; 21 | union { 22 | unsigned char bytes[10]; 23 | long double val; 24 | } bfconvert; 25 | 26 | for (i = 0; i < length; i++) { 27 | sscanf(buf, "%02X", &u); 28 | bfconvert.bytes[i] = u; 29 | buf += 2; 30 | } 31 | 32 | return bfconvert.val; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /logging/cov_serializer.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALIZER_H_INCLUDED 2 | #define SERIALIZER_H_INCLUDED 3 | void cov_serialize(long double, unsigned char*, int); 4 | long double cov_deserialize(char*, int); 5 | #endif 6 | -------------------------------------------------------------------------------- /logging/main.c: -------------------------------------------------------------------------------- 1 | #include "cov_log.h" 2 | #include "cov_checker.h" 3 | 4 | int main(int argc, char*argv[]) { 5 | long double arr[3]; 6 | arr[0] = 0.123451243534534; 7 | arr[1] = 0.235341232353411; 8 | arr[2] = 0.398885094850490; 9 | // cov_log("ideal", "spec.cov", 2, 0.1L, 0.2L); 10 | // cov_log("delta", "spec.cov", 1, 0.0L); 11 | // cov_spec_log(0.1, 0, "spec.cov"); 12 | // cov_log(argv[0], "log.cov", 2, 0.1L, 0.2L); 13 | cov_check("log.cov", "spec.cov", 2); 14 | // cov_arr_log(arr, 3, argv[0], "log.cov"); 15 | // cov_arr_check("log.cov", "spec.cov", 3); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /logging/result: -------------------------------------------------------------------------------- 1 | result=1.230000000000000e-01 2 | result=[0.0, 0.1, 0.3] 3 | tolerance=0.0 4 | -------------------------------------------------------------------------------- /logging/spec.cov: -------------------------------------------------------------------------------- 1 | #ideal 2 | CDCCCCCCCCCCCCCCFB3F CDCCCCCCCCCCCCCCFC3F 3 | #delta 4 | 00000000000000000000 5 | -------------------------------------------------------------------------------- /logging/timers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | 15 | #if defined(__i386__) 16 | 17 | uint64_t rdtsc(void) 18 | { 19 | uint64_t x; 20 | __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); 21 | return x; 22 | } 23 | #elif defined(__x86_64__) 24 | 25 | uint64_t rdtsc(void) 26 | { 27 | unsigned hi, lo; 28 | __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 29 | return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 ); 30 | } 31 | 32 | #elif defined(__powerpc__) 33 | 34 | uint64_t rdtsc(void) 35 | { 36 | uint64_t result=0; 37 | unsigned long upper, lower,tmp; 38 | __asm__ volatile( 39 | "0: \n" 40 | "\tmftbu %0 \n" 41 | "\tmftb %1 \n" 42 | "\tmftbu %2 \n" 43 | "\tcmpw %2,%0 \n" 44 | "\tbne 0b \n" 45 | : "=r"(upper),"=r"(lower),"=r"(tmp) 46 | ); 47 | result = upper; 48 | result = result<<32; 49 | result = result|lower; 50 | 51 | return(result); 52 | } 53 | #else 54 | 55 | #error "No tick counter is available!" 56 | 57 | #endif 58 | 59 | #define MONTONIC_TIME 1 60 | 61 | static void get_time(struct timespec *ts) 62 | { 63 | #if MONTONIC_TIME 64 | int clock_type = CLOCK_MONOTONIC; 65 | #else 66 | int clock_type = CLOCK_REALTIME; 67 | #endif 68 | if (syscall(__NR_clock_gettime, clock_type, ts)) { 69 | printf("clock_gettime(MONOTONIC/REALTIME) failed"); 70 | exit(-1); 71 | } 72 | } 73 | 74 | 75 | uint64_t current_time_ns(void) 76 | { 77 | struct timespec ts; 78 | get_time(&ts); 79 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 80 | } 81 | uint64_t current_time_us(void) 82 | { 83 | struct timespec ts; 84 | get_time(&ts); 85 | return ts.tv_sec * 1000000ULL + ts.tv_nsec/1000; 86 | } 87 | unsigned current_time_sec(void) 88 | { 89 | struct timespec ts; 90 | get_time(&ts); 91 | return ts.tv_sec; 92 | } 93 | -------------------------------------------------------------------------------- /scripts/README: -------------------------------------------------------------------------------- 1 | 2 | brute_force.py 3 | =============== 4 | Runs the brute force algorithm. 5 | 6 | Required files: file.bc search_file.json config_file.json 7 | Command: ./brute_force.py file.bc search_file.json config_file.json [limit] 8 | 9 | config.sh 10 | =========== 11 | Creates the config file (original types for variables). This file can be modified by hand to illustrate a given transformation, which can be applied using the main.py script directly. 12 | 13 | Required files: bitcode file. 14 | Command: ./config.sh file . 15 | Result: config_file.json 16 | 17 | dd2.py 18 | =============== 19 | Run the dd algorithm. 20 | 21 | Required files: file.bc search_file.json config_file.json 22 | More requirements: code should be annotated with logger/checker and timers. 23 | Command: ./dd2.py file.bc search_file.json config_file.json 24 | 25 | dd_par.py 26 | =============== 27 | Run the dd algorithm in parallel. 28 | 29 | Required files: file.bc search_file.json config_file.json 30 | More requirements: code should be annotated with logger/checker and timers with a unique id. See benchmarks/gsl/sum-thresholds/sum4-par/sum.c for example. 31 | - Code should receive an id as input to command line 32 | - Spec is logged as usual as in non-parallel case (using cov_spec_log) 33 | - Log is logged using cov_log to a file called log_#id.cov (#id is the value of id) 34 | - Check is performed using cov_check_par, e.g. cov_check_par("log_#id.cov", "spec.cov", 3, id) 35 | - Score is stored in a file called score_#id.cov (#id is the value of id) 36 | Command: ./dd_par.py file.bc search_file.json config_file.json 37 | 38 | dependencies.sh 39 | ================ 40 | Finds the functions reachable from a given function, and the list of global variables modified by those functions (and to be included in the search space). 41 | 42 | Required files: file.bc 43 | Command: ./dependencies.sh file_name target_function . 44 | The target function is usually "main". 45 | Produced files: include.txt include_global.txt 46 | 47 | main.py 48 | ============== 49 | Transforms a program given a configuration file and checks the result. 50 | 51 | Required files: file.bc, config_file.json, spec.cov 52 | Command: ./main file.bc config_file.json 53 | 54 | pconfig.sh 55 | =========== 56 | Creates the config file (original types for variables). This is used to produce the diff after running DD. 57 | 58 | Required files: bitcode file, exclude.txt include.txt include_global.txt 59 | Optional file: exclude_local.txt 60 | See dependencies.sh to create include.txt and include_global.txt 61 | The file exclude.txt is created by hand, and lists all the functions to be ignored by the analysis. 62 | The file exclude_local.txt is created by hand, and lists all local variables to be excluded from the search space. It assumes unique names given by LLVM, so it is preferably to create the config file without this information first, then identify the variables to be excluded. 63 | 64 | Command: ./pconfig.sh file . 65 | Result: config_file.json 66 | 67 | run.py 68 | =============== 69 | Cleans, compiles, creates search and original config file, and runs the dd algorithm. 70 | 71 | Required files: source files 72 | Command: ./run.sh filename . 73 | 74 | search.sh 75 | ========== 76 | Creates search file for a given bitcode file. 77 | 78 | Required files: bitcode file, exclude.txt include.txt include_global.txt 79 | Optional file: exclude_local.txt 80 | See dependencies.sh to create include.txt and include_global.txt 81 | The file exclude.txt is created by hand, and lists all the functions to be ignored by the analysis. 82 | The file exclude_local.txt is created by hand, and lists all local variables to be excluded from the search space. It assumes unique names given by LLVM, so it is preferably to create the search file without this information first, then identify the variables to be excluded. 83 | 84 | Command: ./search.sh file . 85 | Result: search_file.json 86 | -------------------------------------------------------------------------------- /scripts/brute_force.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import json 4 | import os 5 | import types 6 | import sys 7 | import transform 8 | import utilities 9 | 10 | def print_config(config, configFile): 11 | f = open(configFile, 'w+') 12 | f.write("{\n") 13 | changeList = config["config"] 14 | for change in changeList: 15 | f.write("\t\"" + change.keys()[0] + "\": {\n") 16 | changeValue = change.values()[0] 17 | for valueInfo in changeValue.keys(): 18 | f.write("\t\t\"" + valueInfo + "\": \"" + changeValue[valueInfo] + "\",\n") 19 | f.write("\t},\n") 20 | f.write("}\n") 21 | 22 | def print_diff(changeConfig, originalConfig, diffFile): 23 | f = open(diffFile, 'w+') 24 | originalList = originalConfig["config"] 25 | changeList = changeConfig["config"] 26 | count = 0 27 | while count < len(originalList): 28 | change = changeList[count] 29 | origin = originalList[count] 30 | newType = change.values()[0]["type"] 31 | originType = origin.values()[0]["type"] 32 | if newType != originType: 33 | changeType = change.keys()[0] 34 | if changeType == "localVar": 35 | f.write("localVar: " + change.values()[0]["name"] + " " + originType + " -> " + newType) 36 | elif changeType == "op": 37 | f.write("op: " + change.values()[0]["id"] + originType + " -> " + newType) 38 | count += 1 39 | 40 | def run_config(config, search, bitcodefile, originalConfig, limit): 41 | print_config(config, "config_temp.json") 42 | result = transform.transform(bitcodefile, "config_temp.json") 43 | if result == 1: 44 | print "check VALID_config_" + str(search) + ".json for a valid config file" 45 | print_config(config, "VALID_config_" + bitcodefile + "_" + str(search) + ".json") 46 | print_diff(config, originalConfig, "diff_" + str(search) + ".cov") 47 | utilities.log_config(config, "VALID", "log.bf", search) 48 | elif result == 0: 49 | print "\tINVALID CONFIG" 50 | print_config(config, "INVALID_config_" + bitcodefile + "_" + str(search) + ".json") 51 | utilities.log_config(config, "INVALID", "log.bf", search) 52 | elif result == -1: 53 | print "\tFAIL TYPE 1" 54 | print_config(config, "FAIL1_config_" + bitcodefile + "_" + str(search) + ".json") 55 | utilities.log_config(config, "FAIL1", "log.bf", search) 56 | elif result == -2: 57 | print "\tFAIL TYPE 2" 58 | print_config(config, "FAIL2_config_" + bitcodefile + "_" + str(search) + ".json") 59 | utilities.log_config(config, "FAIL2", "log.bf", search) 60 | elif result == -3: 61 | print "\tFAIL TYPE 3" 62 | print_config(config, "FAIL3_config_" + bitcodefile + "_" + str(search) + ".json") 63 | utilities.log_config(config, "FAIL3", "log.bf", search) 64 | search += 1 65 | if search > limit and limit != -1: 66 | sys.exit(0) 67 | return search 68 | 69 | 70 | def search_config(changeList, changeTypeList, config, search, bitcodefile, originalConfig, limit): 71 | if len(changeList) == 1: 72 | for changeType in changeTypeList[0]: 73 | changeList[0]["type"] = changeType 74 | search = run_config(config, search, bitcodefile, originalConfig, limit) 75 | else: 76 | change = changeList.pop() 77 | changeTypes = changeTypeList.pop() 78 | for changeType in changeTypes: 79 | change["type"] = changeType 80 | search = search_config(changeList, changeTypeList, config, search, bitcodefile, originalConfig, limit) 81 | changeList.append(change) 82 | changeTypeList.append(changeTypes) 83 | return search 84 | 85 | def main(): 86 | bitcodefile = sys.argv[1] 87 | configSearch = sys.argv[2] 88 | original = sys.argv[3] 89 | limit = -1 90 | if len(sys.argv) >= 5: 91 | limit = int(sys.argv[4]) 92 | 93 | # remove config file 94 | try: 95 | os.remove("log.bf") 96 | except OSError: 97 | pass 98 | 99 | config = json.loads(open(configSearch, 'r').read()) 100 | originalConfig = json.loads(open(original, 'r').read()) 101 | allChange = config["config"] 102 | allChangeList = [] 103 | allTypeList = [] 104 | 105 | for change in allChange: 106 | typeList = change.values()[0]["type"] 107 | if isinstance(typeList, list): 108 | allTypeList.append(typeList) 109 | allChangeList.append(change.values()[0]) 110 | 111 | print "Searching for valid config ..." 112 | search_config(allChangeList, allTypeList, config, 0, bitcodefile, originalConfig, limit) 113 | 114 | if __name__ == "__main__": 115 | main() 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /scripts/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ################################### 4 | # Shell script to remove output files 5 | # Use: ./clean.sh . 6 | # #################################### 7 | 8 | echo "Cleaning files" 9 | rm -f $1/*.o $1/FAIL* $1/INVALID_config* $1/VALID_config* 10 | rm -f $1/output.txt $1/log.cov *~ *.metrics 11 | rm -f $1/config_temp.json 12 | rm -f $1/diff_*_* 13 | rm -f $1/m_* 14 | rm -f $1/dd2_diff_*_* 15 | rm -f $1/dd2_valid_*_* 16 | rm -f $1/i_m_* 17 | rm -f $1/log.cov 18 | rm -f $1/log.dd 19 | rm -f $1/counters.bc $1/cov* $1/temp_*.bc $1/demo_fn.bc 20 | #rm -f $1/score.cov $1/sat.cov 21 | -------------------------------------------------------------------------------- /scripts/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ################################### 4 | # Shell script to remove output files 5 | # Use: ./compile.sh file . 6 | # #################################### 7 | 8 | loggingPath=$CORVETTE_PATH"/logging" 9 | 10 | clang -emit-llvm -c $2/$1.c -o $2/temp_$1.bc 11 | clang -emit-llvm -c $loggingPath/cov_checker.c -o $2/cov_checker.bc 12 | clang -emit-llvm -c $loggingPath/cov_serializer.c -o $2/cov_serializer.bc 13 | clang -emit-llvm -c $loggingPath/cov_log.c -o $2/cov_log.bc 14 | llvm-link -o $2/$1.bc $2/temp_$1.bc $2/cov_checker.bc $2/cov_serializer.bc $2/cov_log.bc 15 | 16 | -------------------------------------------------------------------------------- /scripts/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ############################################################# 4 | # Shell script to create configuration file with original types 5 | # Use: ./config.sh name_of_bc_file 6 | # ############################################################# 7 | 8 | arch=`uname -a` 9 | name=${arch:0:6} 10 | 11 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 12 | 13 | if [ "$name" = "Darwin" ]; then 14 | sharedLib=$CORVETTE_PATH"/src/Passes.dylib" 15 | fi 16 | 17 | varFlags="--only-arrays --only-scalars --funs" 18 | 19 | echo "Creating type configuration file" config_$1.json 20 | opt -load $sharedLib -config-file $varFlags $1.bc --filename config_$1.json > $1.tmp 21 | 22 | # cleaning up 23 | rm -f $1.tmp 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /scripts/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ################################### 4 | # Shell script to print coverage trace 5 | # Use: ./coverage.sh file . 6 | # #################################### 7 | 8 | sourcePath=$CORVETTE_PATH"/src" 9 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 10 | 11 | # compile counters into driver 12 | clang -emit-llvm -c $sourcePath/branches.c -o $2/branches.bc 13 | llvm-link -o $2/temp_$1.bc $2/$1.bc $2/branches.bc 14 | 15 | # run pass to instrument code 16 | opt -load $sharedLib -coverage --exclude $sourcePath/exclude_coverage.txt $2/temp_$1.bc > $2/c_$1.bc 17 | echo "Done instrumenting program with coverage information" c_$1.bc 18 | 19 | # cleaning up 20 | rm -f $2/temp_$1.bc 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /scripts/dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ########################################## 4 | # Shell script to run the metrics LLVM pass 5 | # Use: ./dependencies.sh name_of_bc_file function_main 6 | # ########################################## 7 | 8 | arch=`uname -a` 9 | name=${arch:0:6} 10 | 11 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 12 | 13 | if [ "$name" = "Darwin" ]; then 14 | sharedLib=$CORVETTE_PATH"/src/Passes.dylib" 15 | fi 16 | 17 | echo "Finding dependencies file for " $1.bc 18 | opt -load $sharedLib -create-call-dependency $1.bc --call-main $2 > $1.tmp 19 | 20 | # cleaning up 21 | rm -f $1.tmp 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /scripts/find_inputs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | 4 | import os 5 | import platform 6 | import sys 7 | from subprocess import CalledProcessError, PIPE, Popen, call 8 | 9 | coverage = set() 10 | count = 0 11 | fininfile = open('final_inputs', 'w') 12 | for i in range(0, 10000): 13 | # remove inputs file 14 | command = ['rm', '-f', 'inputs'] 15 | call(command, stdin=None, stdout=None, stderr=None) 16 | # remove coverage file 17 | command = ['rm', "-f", 'coverage.cov'] 18 | call(command, stdin=None, stdout=None, stderr=None) 19 | # execute 20 | command = ['lli', 'c_' + sys.argv[1] + '.bc'] 21 | retval = call(command, stdin=None, stdout=None, stderr=None) 22 | # reading coverage output 23 | if retval == 0: 24 | covstr = "" 25 | with open ('coverage.cov', 'r') as myfile: 26 | covstr = myfile.read().replace('\n', '') 27 | if covstr not in coverage: 28 | coverage.add(covstr) 29 | count = count+1 30 | print i 31 | infile = open('inputs', 'r') 32 | firstline = infile.readline() 33 | firstline = infile.readline() 34 | firstline = firstline.strip() 35 | infile.close() 36 | fininfile.write(firstline + '\n') 37 | if count == 10: 38 | break 39 | fininfile.close() 40 | -------------------------------------------------------------------------------- /scripts/instrument.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ################################### 4 | # Shell script to remove output files 5 | # Use: ./instrument.sh file . 6 | # #################################### 7 | 8 | sourcePath=$CORVETTE_PATH"/src" 9 | sharedLib=$sourcePath"/Passes.so" 10 | 11 | # compile counters and link with bitcode to be instrumented 12 | clang -emit-llvm -c $sourcePath/counters.c -o $2/counters.bc 13 | llvm-link -o $2/temp_$1.bc $2/$1.bc $2/counters.bc 14 | 15 | # run pass to instrument code 16 | opt -load $sharedLib -instrument --exclude $sourcePath/exclude_instrument.txt $2/temp_$1.bc > $2/i_$1.bc 17 | echo "Done instrumenting program" i_$1.bc 18 | 19 | # cleaning up 20 | rm -f $2/temp_$1.bc 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /scripts/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import transform2 5 | 6 | # ####################################################### 7 | # Sample python script that invokes the transform script 8 | # ####################################################### 9 | 10 | def main(): 11 | 12 | # calling transform script 13 | bitcodefile = sys.argv[1] 14 | configfile = sys.argv[2] 15 | result = transform2.transform(bitcodefile, configfile) 16 | print "Return value: " + str(result) 17 | 18 | if __name__ == "__main__": 19 | main() 20 | -------------------------------------------------------------------------------- /scripts/metrics.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ########################################## 4 | # Shell script to run the metrics LLVM pass 5 | # Use: ./metrics.sh name_of_bc_file 6 | # ########################################## 7 | 8 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 9 | 10 | echo "Creating metrics file for " $1.bc 11 | opt -load $sharedLib -measure-metric $1.bc > $1.metrics 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /scripts/par.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import multiprocessing 3 | import time 4 | import os, platform, sys 5 | from subprocess import CalledProcessError, PIPE, Popen, call 6 | 7 | class Consumer(multiprocessing.Process): 8 | 9 | def __init__(self, task_queue, result_queue): 10 | multiprocessing.Process.__init__(self) 11 | self.task_queue = task_queue 12 | self.result_queue = result_queue 13 | 14 | def run(self): 15 | proc_name = self.name 16 | while True: 17 | next_task = self.task_queue.get() 18 | if next_task is None: 19 | # Poison pill means we should exit 20 | print '%s: Exiting' % proc_name 21 | break 22 | print '%s' % (proc_name) 23 | # print '%s: %s' % (proc_name, next_task) 24 | answer = next_task() 25 | self.result_queue.put(answer) 26 | return 27 | 28 | 29 | class Task(object): 30 | def __init__(self, a, b): 31 | self.a = a 32 | self.b = b 33 | def __call__(self): 34 | command = ['./hello', str(self.a)] 35 | call(command, stdin=None, stdout=None, stderr=None) 36 | return '%s * %s = %s' % (self.a, self.b, self.a * self.b) 37 | def __str__(self): 38 | return '%s * %s' % (self.a, self.b) 39 | 40 | 41 | if __name__ == '__main__': 42 | # Establish communication queues 43 | tasks = multiprocessing.Queue() 44 | results = multiprocessing.Queue() 45 | 46 | # Start consumers 47 | num_consumers = multiprocessing.cpu_count() * 2 48 | print 'Creating %d consumers' % num_consumers 49 | consumers = [ Consumer(tasks, results) 50 | for i in xrange(num_consumers) ] 51 | for w in consumers: 52 | w.start() 53 | 54 | # Enqueue jobs 55 | num_jobs = 100 56 | for i in xrange(num_jobs): 57 | tasks.put(Task(i, i)) 58 | 59 | # Add a poison pill for each consumer 60 | for i in xrange(num_consumers): 61 | tasks.put(None) 62 | 63 | # Start printing results 64 | while num_jobs: 65 | result = results.get() 66 | # print 'Result:', result 67 | num_jobs -= 1 68 | -------------------------------------------------------------------------------- /scripts/pconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ############################################################# 4 | # Shell script to create configuration file with original types 5 | # Use: ./config.sh name_of_bc_file 6 | # ############################################################# 7 | 8 | 9 | 10 | 11 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 12 | 13 | arch=`uname -a` 14 | name=${arch:0:6} 15 | 16 | if [ "$name" = "Darwin" ]; then 17 | sharedLib=$CORVETTE_PATH"/src/Passes.dylib" 18 | fi 19 | 20 | varFlags="--only-arrays --only-scalars --funs" 21 | 22 | echo "Creating type configuration file" config_$1.json 23 | opt -load $sharedLib -config-file $varFlags --pformat $1.bc --filename config_$1.json > $1.tmp 24 | 25 | # cleaning up 26 | rm -f $1.tmp 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /scripts/print_functions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ############################################################# 4 | # Shell script to create search file for a given program 5 | # Use: ./print_functions.sh name_of_bc_file 6 | # ############################################################# 7 | 8 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 9 | 10 | arch=`uname -a` 11 | name=${arch:0:6} 12 | 13 | if [ "$name" = "Darwin" ]; then 14 | sharedLib=$CORVETTE_PATH"/src/Passes.dylib" 15 | fi 16 | 17 | echo "Printing function names" 18 | opt -load $sharedLib -print-names $1.bc -disable-output 19 | -------------------------------------------------------------------------------- /scripts/proc.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import time 3 | import sys 4 | 5 | class Timeout(Exception): 6 | pass 7 | 8 | def run(command, timeout=30): 9 | proc = subprocess.Popen(command, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 10 | poll_seconds = .250 11 | deadline = time.time()+timeout 12 | while time.time() < deadline and proc.poll() == None: 13 | time.sleep(poll_seconds) 14 | 15 | if proc.poll() == None: 16 | if float(sys.version[:3]) >= 2.6: 17 | proc.terminate() 18 | raise Timeout() 19 | 20 | return proc.returncode 21 | -------------------------------------------------------------------------------- /scripts/proc.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/scripts/proc.pyc -------------------------------------------------------------------------------- /scripts/replace_calls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ############################################################# 4 | # Shell script to create search file for a given program 5 | # Use: ./print_functions.sh name_of_bc_file 6 | # ############################################################# 7 | 8 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 9 | 10 | # if Darwin, the file extension is different 11 | arch=`uname -a` 12 | name=${arch:0:6} 13 | if [ "$name" = "Darwin" ]; then 14 | sharedLib=$CORVETTE_PATH"/src/Passes.dylib" 15 | fi 16 | 17 | echo "Replacing function calls" 18 | opt -load $sharedLib -json-config=config_$1.json -function-calls $1.bc > transformed.bc 19 | -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ############################################################# 4 | # Shell script to create configuration file with original types 5 | # Use: ./run.sh name_of_bc_file . 6 | # ############################################################# 7 | 8 | scripts=$CORVETTE_PATH"/scripts" 9 | 10 | sh $scripts/clean.sh $2 11 | 12 | sh $scripts/compile.sh $1 $2 13 | 14 | #sh $scripts/search.sh $1 15 | 16 | #sh $scripts/pconfig.sh $1 17 | 18 | echo "Running dd algorithm" 19 | $scripts/dd.py $1.bc searchFile.json $1.json 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /scripts/run_configs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | 4 | import sys 5 | from subprocess import CalledProcessError, PIPE, Popen, call 6 | 7 | def calculate_speedup(configs, dir): 8 | # calculating speedup 9 | infile = open(dir + '/score.cov', 'r') 10 | original = int(infile.readline()) 11 | infile.close() 12 | 13 | for i in range(1,configs+1): 14 | infile = open(dir + '/score' + str(i) + '.cov', 'r') 15 | modified = int(infile.readline()) 16 | diff = original - modified 17 | speedup = (diff*100.0)/original 18 | print 'Speedup ' + str(i) + ':' + str(speedup) 19 | infile.close() 20 | 21 | 22 | def main(): 23 | dir = sys.argv[3] 24 | 25 | # running original 26 | command = [dir + '/' + sys.argv[1] + '_timers'] 27 | call(command, stdin=None, stdout=None, stderr=None) 28 | command = ['cat', dir + '/score.cov'] 29 | call(command, stdin=None, stdout=None, stderr=None) 30 | 31 | # running configurations 32 | n = int(sys.argv[2]) 33 | for i in range(1,n+1): 34 | command = [dir + '/config' + str(i) + '_timers'] 35 | call(command, stdin=None, stdout=None, stderr=None) 36 | command = ['cat', dir + '/score' + str(i) + '.cov'] 37 | call(command, stdin=None, stdout=None, stderr=None) 38 | 39 | calculate_speedup(n, dir) 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | 45 | 46 | -------------------------------------------------------------------------------- /scripts/search.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ############################################################# 4 | # Shell script to create search file for a given program 5 | # Use: ./search.sh name_of_bc_file 6 | # ############################################################# 7 | 8 | sharedLib=$CORVETTE_PATH"/src/Passes.so" 9 | 10 | arch=`uname -a` 11 | name=${arch:0:6} 12 | 13 | if [ "$name" = "Darwin" ]; then 14 | sharedLib=$CORVETTE_PATH"/src/Passes.dylib" 15 | fi 16 | 17 | varFlags="--only-arrays --only-scalars --funs" 18 | 19 | echo "Creating search file search file" search_$1.json 20 | opt -load $sharedLib -search-file --original-type $varFlags $1.bc --filename search_$1.json > $1.tmp 21 | 22 | # cleaning up 23 | rm -f $1.tmp 24 | -------------------------------------------------------------------------------- /scripts/transform.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import proc 5 | import platform 6 | import sys 7 | from subprocess import CalledProcessError, PIPE, Popen, call 8 | 9 | 10 | # ############################################################# 11 | # Python script that transforms code, runs it and checks result 12 | # See main.py for a sample on how to invoke this script 13 | # ############################################################# 14 | 15 | def transform(bitcodefile, configfile): 16 | 17 | # setting some variables 18 | corvettepath = os.getenv("CORVETTE_PATH") 19 | 20 | if platform.system() == 'Darwin': 21 | sharedlib = corvettepath + "/precision-tuning/Passes.dylib" 22 | else: 23 | sharedlib = corvettepath + "/precision-tuning/Passes.so" 24 | 25 | # modified bitcode file 26 | mbitcodefile = "m_" + sys.argv[1] 27 | mbitcode = open(mbitcodefile, 'w') 28 | 29 | # modified + optimized bitcode file 30 | obitcodefile = "o_" + sys.argv[1] 31 | obitcode = open(obitcodefile, 'w') 32 | 33 | # temp bitcode file 34 | tempfile = "temp_" + sys.argv[1] 35 | temp = open(tempfile, 'w') 36 | 37 | output = open("output.txt", 'w') 38 | 39 | # ###################################### 40 | # running the transformation LLVM passes 41 | # passes are run in the order the appear 42 | # ###################################### 43 | #command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-adjust-operators", "--die", "--time-passes", bitcodefile] 44 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-adjust-operators", "--die", bitcodefile] 45 | retval = call(command, stdin=None, stdout=mbitcode, stderr=None) 46 | 47 | # return -1 if running LLVM passes fails 48 | if retval <> 0: 49 | return -1 50 | 51 | # ########################### 52 | # removing redundant castings 53 | # ########################### 54 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-remove-dead-casting", mbitcodefile] 55 | retval = call(command, stdin=None, stdout=obitcode, stderr=None) 56 | 57 | # return -3 if removing dead castings fails 58 | if retval <> 0: 59 | return -3 60 | 61 | # We aren't using stats, so we don't need to run pass 62 | #command = ['opt', '-load', sharedlib, "-measure-metric", obitcodefile] 63 | #retval = call(command, stdin=None, stdout=temp, stderr=None) 64 | 65 | # ###################################### 66 | # running the modified+optimized program 67 | # ###################################### 68 | command = ['lli', obitcodefile] 69 | #command = ['lli', mbitcodefile] 70 | # retval = call(command, stdin=None, stdout=output, stderr=None) 71 | try: 72 | retval = proc.run(command, timeout=30) 73 | except proc.Timeout: 74 | return -4 75 | output.close() 76 | 77 | # return -2 if running the modified+optimized bitcode fails 78 | if retval <> 0: 79 | return -2 80 | 81 | # reading output 82 | output = open("sat.cov", 'r') 83 | firstline = output.readline() 84 | firstline = firstline.strip() 85 | if (firstline == "true"): 86 | # ########################## 87 | # get the dynamic score 88 | # ######################### 89 | # mbitcodefile_name = mbitcodefile[:-3] # remove .bc 90 | # command = [corvettepath + "/benchmarks/gsl/instrument.sh", mbitcodefile_name, "."] 91 | # call(command, stdin=None, stdout=None, stderr=None) 92 | # command = ['lli', obitcodefile] 93 | # call(command, stdin=None, stdout=None, stderr=None) 94 | command = ['llc', obitcodefile, '-o', sys.argv[1] + '.s'] 95 | call(command, stdin=None, stdout=None, stderr=None) 96 | command = ['gcc', sys.argv[1] + '.s', '-lm', '-o', sys.argv[1] + '.out'] 97 | call(command, stdin=None, stdout=None, stderr=None) 98 | command = ['./' + sys.argv[1] + '.out'] 99 | call(command, stdin=None, stdout=None, stderr=None) 100 | return 1 101 | else: 102 | return 0 103 | 104 | -------------------------------------------------------------------------------- /scripts/transform2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import proc 5 | import platform 6 | import sys 7 | from subprocess import CalledProcessError, PIPE, Popen, call 8 | 9 | 10 | # ############################################################# 11 | # Python script that transforms code, runs it and checks result 12 | # See main.py for a sample on how to invoke this script 13 | # ############################################################# 14 | 15 | def transform(bitcodefile, configfile): 16 | 17 | # setting some variables 18 | corvettepath = os.getenv("CORVETTE_PATH") 19 | 20 | if platform.system() == 'Darwin': 21 | sharedlib = corvettepath + "/src/Passes.dylib" 22 | else: 23 | sharedlib = corvettepath + "/src/Passes.so" 24 | 25 | # modified bitcode file 26 | mbitcodefile = "m_" + sys.argv[1] 27 | mbitcode = open(mbitcodefile, 'w') 28 | 29 | # temp bitcode file 30 | tempfile = "temp_" + sys.argv[1] 31 | temp = open(tempfile, 'w') 32 | 33 | output = open("output.txt", 'w') 34 | 35 | # ###################################### 36 | # running the transformation LLVM passes 37 | # passes are run in the order the appear 38 | # ###################################### 39 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-adjust-operators", bitcodefile] 40 | retval = call(command, stdin=None, stdout=mbitcode, stderr=None) 41 | 42 | # return -1 if running LLVM passes fails 43 | if retval <> 0: 44 | return -1 45 | 46 | # running modified bitcode 47 | command = ['opt', '-O2', mbitcodefile, '-o', sys.argv[1] + '_opt.bc'] 48 | call(command, stdin=None, stdout=None, stderr=None) 49 | command = ['llc', sys.argv[1] + '_opt.bc', '-o', sys.argv[1] + '.s'] 50 | call(command, stdin=None, stdout=None, stderr=None) 51 | command = ['clang', sys.argv[1] + '.s', '-lm', '-o', sys.argv[1] + '.out'] 52 | call(command, stdin=None, stdout=None, stderr=None) 53 | command = ['./' + sys.argv[1] + '.out'] 54 | retval = call(command, stdin=None, stdout=None, stderr=None) 55 | 56 | #try: 57 | # retval = proc.run(command, timeout=5) 58 | #except proc.Timeout: 59 | # return -4 60 | 61 | # return -3 if crashed when run 62 | if retval <> 0: 63 | return -3 64 | 65 | output = open("sat.cov", 'r') 66 | firstline = output.readline() 67 | firstline = firstline.strip() 68 | if (firstline == "true"): 69 | return 1 70 | else: 71 | return 0 72 | 73 | -------------------------------------------------------------------------------- /scripts/transform2.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/scripts/transform2.pyc -------------------------------------------------------------------------------- /scripts/transform_notime.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import proc 5 | import platform 6 | import sys 7 | from subprocess import CalledProcessError, PIPE, Popen, call 8 | 9 | 10 | # ############################################################# 11 | # Python script that transforms code, runs it and checks result 12 | # See main.py for a sample on how to invoke this script 13 | # ############################################################# 14 | 15 | def transform(bitcodefile, configfile): 16 | 17 | # setting some variables 18 | corvettepath = os.getenv("CORVETTE_PATH") 19 | 20 | if platform.system() == 'Darwin': 21 | sharedlib = corvettepath + "/src/Passes.dylib" 22 | else: 23 | sharedlib = corvettepath + "/src/Passes.so" 24 | 25 | # modified bitcode file 26 | mbitcodefile = "m_" + sys.argv[1] 27 | mbitcode = open(mbitcodefile, 'w') 28 | 29 | # modified + optimized bitcode file 30 | obitcodefile = "o_" + sys.argv[1] 31 | obitcode = open(obitcodefile, 'w') 32 | 33 | # temp bitcode file 34 | tempfile = "temp_" + sys.argv[1] 35 | temp = open(tempfile, 'w') 36 | 37 | output = open("output.txt", 'w') 38 | 39 | # ###################################### 40 | # running the transformation LLVM passes 41 | # passes are run in the order the appear 42 | # ###################################### 43 | #command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-adjust-operators", "--die", "--time-passes", bitcodefile] 44 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-adjust-operators", "--die", bitcodefile] 45 | retval = call(command, stdin=None, stdout=mbitcode, stderr=None) 46 | 47 | # return -1 if running LLVM passes fails 48 | if retval <> 0: 49 | return -1 50 | 51 | # ########################### 52 | # removing redundant castings 53 | # ########################### 54 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-remove-dead-casting", mbitcodefile] 55 | retval = call(command, stdin=None, stdout=obitcode, stderr=None) 56 | 57 | # return -3 if removing dead castings fails 58 | if retval <> 0: 59 | return -3 60 | 61 | # We aren't using stats, so we don't need to run pass 62 | #command = ['opt', '-load', sharedlib, "-measure-metric", obitcodefile] 63 | #retval = call(command, stdin=None, stdout=temp, stderr=None) 64 | 65 | # ###################################### 66 | # running the modified+optimized program 67 | # ###################################### 68 | command = ['lli', obitcodefile] 69 | #command = ['lli', mbitcodefile] 70 | # retval = call(command, stdin=None, stdout=output, stderr=None) 71 | try: 72 | retval = proc.run(command, timeout=30) 73 | except proc.Timeout: 74 | return -4 75 | output.close() 76 | 77 | # return -2 if running the modified+optimized bitcode fails 78 | if retval <> 0: 79 | return -2 80 | 81 | # reading output 82 | output = open("sat.cov", 'r') 83 | firstline = output.readline() 84 | firstline = firstline.strip() 85 | if (firstline == "true"): 86 | # ########################## 87 | # get the dynamic score 88 | # ######################### 89 | # mbitcodefile_name = mbitcodefile[:-3] # remove .bc 90 | # command = [corvettepath + "/benchmarks/gsl/instrument.sh", mbitcodefile_name, "."] 91 | # call(command, stdin=None, stdout=None, stderr=None) 92 | # command = ['lli', obitcodefile] 93 | # call(command, stdin=None, stdout=None, stderr=None) 94 | # command = ['llc', obitcodefile, '-o', sys.argv[1] + '.s'] 95 | # call(command, stdin=None, stdout=None, stderr=None) 96 | # command = ['gcc', sys.argv[1] + '.s', '-lm', '-o', sys.argv[1] + '.out'] 97 | # call(command, stdin=None, stdout=None, stderr=None) 98 | # command = ['./' + sys.argv[1] + '.out'] 99 | # call(command, stdin=None, stdout=None, stderr=None) 100 | return 1 101 | else: 102 | return 0 103 | 104 | -------------------------------------------------------------------------------- /scripts/transform_par.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import proc 5 | import platform 6 | import sys 7 | from subprocess import CalledProcessError, PIPE, Popen, call 8 | 9 | 10 | # ############################################################# 11 | # Python script that transforms code, runs it and checks result 12 | # See main.py for a sample on how to invoke this script 13 | # ############################################################# 14 | 15 | def transform(bitcodefile, configfile, inx): 16 | 17 | # setting some variables 18 | corvettepath = os.getenv("CORVETTE_PATH") 19 | 20 | if platform.system() == 'Darwin': 21 | sharedlib = corvettepath + "/src/Passes.dylib" 22 | else: 23 | sharedlib = corvettepath + "/src/Passes.so" 24 | 25 | # modified bitcode file 26 | mbitcodefile = "m_" + sys.argv[1] + "_" + str(inx) 27 | mbitcode = open(mbitcodefile, 'w') 28 | 29 | # modified + optimized bitcode file 30 | obitcodefile = "o_" + sys.argv[1] + "_" + str(inx) 31 | obitcode = open(obitcodefile, 'w') 32 | 33 | # temp bitcode file 34 | tempfile = "temp_" + sys.argv[1] + "_" + str(inx) 35 | temp = open(tempfile, 'w') 36 | 37 | output = open("output.txt", 'w') 38 | 39 | # ###################################### 40 | # running the transformation LLVM passes 41 | # passes are run in the order the appear 42 | # ###################################### 43 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-adjust-operators", "--die", bitcodefile] 44 | retval = call(command, stdin=None, stdout=mbitcode, stderr=None) 45 | 46 | # return -1 if running LLVM passes fails 47 | if retval <> 0: 48 | return -1 49 | 50 | # ########################### 51 | # removing redundant castings 52 | # ########################### 53 | command = ['opt', '-load', sharedlib, "-json-config=" + configfile, "-remove-dead-casting", mbitcodefile] 54 | retval = call(command, stdin=None, stdout=obitcode, stderr=None) 55 | 56 | # return -3 if removing dead castings fails 57 | if retval <> 0: 58 | return -3 59 | 60 | # We aren't using stats, so we don't need to run pass 61 | #command = ['opt', '-load', sharedlib, "-measure-metric", obitcodefile] 62 | #retval = call(command, stdin=None, stdout=temp, stderr=None) 63 | 64 | # ###################################### 65 | # running the modified+optimized program 66 | # ###################################### 67 | command = ['lli', obitcodefile, str(inx)] 68 | #command = ['lli', mbitcodefile] 69 | # retval = call(command, stdin=None, stdout=output, stderr=None) 70 | try: 71 | retval = proc.run(command, timeout=30) 72 | except proc.Timeout: 73 | return -4 74 | output.close() 75 | 76 | # return -2 if running the modified+optimized bitcode fails 77 | if retval <> 0: 78 | return -2 79 | 80 | # reading output 81 | output = open("sat_" + str(inx) + ".cov", 'r') 82 | firstline = output.readline() 83 | firstline = firstline.strip() 84 | if (firstline == "true"): 85 | # ########################## 86 | # get the dynamic score 87 | # ######################### 88 | command = ['llc', obitcodefile, '-o', sys.argv[1] + "_" + str(inx) + '.s'] 89 | call(command, stdin=None, stdout=None, stderr=None) 90 | command = ['gcc', sys.argv[1] + "_" + str(inx) + '.s', '-lm', '-o', sys.argv[1] + "_" + str(inx) + '.out'] 91 | call(command, stdin=None, stdout=None, stderr=None) 92 | command = ['./' + sys.argv[1] + "_" + str(inx) + '.out'] 93 | call(command, stdin=None, stdout=None, stderr=None) 94 | 95 | return 1 96 | else: 97 | return 0 98 | 99 | -------------------------------------------------------------------------------- /scripts/transform_par.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/scripts/transform_par.pyc -------------------------------------------------------------------------------- /scripts/utilities.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/scripts/utilities.pyc -------------------------------------------------------------------------------- /src/AdjustOperators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ADJUST_OPERATORS_GUARD 2 | #define ADJUST_OPERATORS_GUARD 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace llvm { 14 | class Value; 15 | class BinaryOperator; 16 | class FCmpInst; 17 | class Type; 18 | } 19 | 20 | using namespace std; 21 | using namespace llvm; 22 | extern cl::opt ExcludedFunctionsFileName; 23 | extern cl::opt IncludedFunctionsFileName; 24 | 25 | 26 | class AdjustOperators : public ModulePass { 27 | public: 28 | AdjustOperators() : ModulePass(ID) {} 29 | 30 | void doInitialization(Module &module); 31 | 32 | bool runOnFunction(Function &function); 33 | 34 | void clean(); 35 | 36 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 37 | 38 | virtual bool runOnModule(Module &module); 39 | 40 | static char ID; // Pass identification, replacement for typeid 41 | 42 | private: 43 | void changeBinaryOperator(BinaryOperator* old_target); 44 | 45 | void changeBinaryOperatorInt(BinaryOperator* old_target); 46 | 47 | void changeFCmpInst(FCmpInst* old_target); 48 | 49 | DebugInfoFinder debugInfo; 50 | 51 | vector erase; 52 | 53 | set excludedFunctions; 54 | 55 | set includedFunctions; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/Change.cpp: -------------------------------------------------------------------------------- 1 | #include "Change.hpp" 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace llvm; 8 | 9 | Change::Change(Types aType, Value* aValue) { 10 | type = aType; 11 | value = aValue; 12 | field = -1; 13 | } 14 | 15 | Change::Change(Types aType, Value* aValue, int aField) { 16 | type = aType; 17 | value = aValue; 18 | field = aField; 19 | } 20 | 21 | Value* Change::getValue() { 22 | return value; 23 | } 24 | 25 | Types Change::getType() { 26 | return type; 27 | } 28 | 29 | int Change::getField() { 30 | return field; 31 | } 32 | -------------------------------------------------------------------------------- /src/Change.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHANGE_GUARD 2 | #define CHANGE_GUARD 1 3 | 4 | #include 5 | #include 6 | 7 | namespace llvm { 8 | class Value; 9 | } 10 | 11 | using namespace llvm; 12 | using namespace std; 13 | 14 | typedef vector Types; 15 | 16 | class Change { 17 | public: 18 | Change(Types, Value*); 19 | Change(Types, Value*, int); 20 | ~Change(); 21 | 22 | Value* getValue(); 23 | 24 | Types getType(); 25 | 26 | int getField(); 27 | 28 | protected: 29 | Value* value; 30 | Types type; 31 | int field; 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/ChangePrecision.cpp: -------------------------------------------------------------------------------- 1 | //#include "CollectVars.hpp" 2 | #include "ChangePrecision.hpp" 3 | #include "Transformer.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | cl::opt ConfigFileName("config", cl::value_desc("filename"), cl::desc("Configuration input file"), cl::init("config.txt")); 18 | 19 | bool ChangePrecision::doInitialization(Module &module) { 20 | 21 | debugInfo.processModule(module); 22 | 23 | //CollectVars &vars = getAnalysis(); 24 | //locals = vars.getLocals(); 25 | 26 | // read variables from config file 27 | 28 | string sfunction; 29 | string svariable; 30 | 31 | ifstream config(ConfigFileName.c_str()); 32 | if (config.is_open()) { 33 | 34 | while(config >> sfunction >> svariable) { 35 | const ValueSymbolTable& moduleSymbolTable = module.getValueSymbolTable(); 36 | Value *vfunction = moduleSymbolTable.lookup(sfunction); 37 | Function *function = dyn_cast(vfunction); 38 | 39 | if (function) { 40 | const ValueSymbolTable& symbolTable = function->getValueSymbolTable(); 41 | Value* target = symbolTable.lookup(svariable); 42 | 43 | if (target) { 44 | locals[function].push_back(target); 45 | } 46 | } 47 | 48 | } // while 49 | } 50 | else { 51 | errs() << "ERROR: Could not open configuration file\n"; 52 | } 53 | 54 | return false; 55 | } 56 | 57 | 58 | // NOTE: bitcode is verified at the end. 59 | 60 | bool ChangePrecision::runOnModule(Module &M) { 61 | 62 | doInitialization(M); 63 | 64 | for(Module::iterator function = M.begin(), end = M.end(); function != end; function++) { 65 | 66 | map::iterator it = locals.find(function); 67 | 68 | if (it != locals.end()) { 69 | Variables &vars = locals[function]; 70 | 71 | for(unsigned int i = 0; i < vars.size(); i++) { 72 | 73 | // creating new AllocaInst 74 | Value* target = vars[i]; 75 | //errs() << "Changing variable: " << function->getName() << ":" << target->getName() << "\n"; 76 | 77 | AllocaInst* old_target = dyn_cast(target); 78 | LLVMContext &context = function->getContext(); 79 | Type* type = Type::getFloatTy(context); 80 | unsigned alignment = 4; 81 | 82 | AllocaInst* new_target = new AllocaInst(type, 0, alignment, "new", old_target); 83 | new_target->takeName(old_target); 84 | 85 | // iterating through instructions using old AllocaInst 86 | Value::use_iterator it = target->use_begin(); 87 | for(; it != target->use_end(); it++) { 88 | Transformer::transform(it, new_target, type); 89 | } 90 | old_target->eraseFromParent(); 91 | } 92 | } 93 | //function->dump(); 94 | } 95 | 96 | return false; 97 | } 98 | 99 | 100 | void ChangePrecision::getAnalysisUsage(AnalysisUsage &AU) const { 101 | AU.setPreservesAll(); 102 | //AU.addRequired(); 103 | } 104 | 105 | 106 | char ChangePrecision::ID = 0; 107 | static const RegisterPass registration("d2f", "Reduce the precision of a program"); 108 | -------------------------------------------------------------------------------- /src/ChangePrecision.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHANGE_PRECISION_GUARD 2 | #define CHANGE_PRECISION_GUARD 1 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace llvm { 11 | class Value; 12 | } 13 | 14 | using namespace std; 15 | using namespace llvm; 16 | 17 | typedef vector Variables; 18 | 19 | class ChangePrecision : public ModulePass { 20 | 21 | public: 22 | ChangePrecision() : ModulePass(ID) {} 23 | 24 | bool doInitialization(Module &M); 25 | 26 | bool doFinalization(Module &M); 27 | 28 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 29 | 30 | virtual bool runOnModule(Module &M); 31 | 32 | static char ID; // Pass identification, replacement for typeid 33 | 34 | private: 35 | DebugInfoFinder debugInfo; 36 | 37 | map locals; 38 | 39 | }; 40 | 41 | #endif // CHANGE_PRECISION_GUARD 42 | -------------------------------------------------------------------------------- /src/Coverage.cpp: -------------------------------------------------------------------------------- 1 | #include "Coverage.hpp" 2 | 3 | #include 4 | #include 5 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | void Coverage::doInitialization(Module &module) 12 | { 13 | debugInfo.processModule(module); 14 | 15 | ifstream inFile(ExcludedFunctionsFileName.c_str()); 16 | string name; 17 | 18 | if (!inFile) { 19 | errs() << "Unable to open " << ExcludedFunctionsFileName << '\n'; 20 | exit(1); 21 | } 22 | 23 | while(inFile >> name) { 24 | excludedFunctions.insert(name); 25 | } 26 | inFile.close(); 27 | 28 | return; 29 | } 30 | 31 | bool Coverage::runOnModule(Module &module) 32 | { 33 | doInitialization(module); 34 | 35 | // iterate through functions in module 36 | for (Module::iterator f = module.begin(), fe = module.end(); f != fe; f++) 37 | { 38 | runOnFunction(module, *f); 39 | } 40 | 41 | return true; 42 | } 43 | 44 | bool Coverage::runOnFunction(Module &module, Function &function) 45 | { 46 | int blockId = 0; 47 | int branchId = 0; 48 | if (! function.isDeclaration() && (excludedFunctions.find(function.getName()) == excludedFunctions.end())) 49 | { 50 | bool printBranchTo = false; 51 | for (Function::iterator b = function.begin(), be = function.end(); b != be; b++) 52 | { 53 | for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) 54 | { 55 | blockId++; 56 | 57 | // 58 | // printing target block id 59 | // 60 | if (!dyn_cast(i) && printBranchTo) 61 | { 62 | std::vector args; 63 | 64 | IntegerType *int32Type = Type::getInt32Ty(module.getContext()); 65 | 66 | ConstantInt* arg0 = ConstantInt::getSigned(int32Type, blockId); 67 | 68 | args.push_back((Value*)arg0); 69 | 70 | ArrayRef *arrayRef = new ArrayRef(args); 71 | 72 | CallInst::Create(module.getFunction("printBranchTo"), *arrayRef, "", i); 73 | printBranchTo = false; 74 | } 75 | 76 | // 77 | // printing branch id 78 | // TODO: switch instruction 79 | // 80 | if (dyn_cast(i) || dyn_cast(i)) 81 | { 82 | branchId++; 83 | std::vector args; 84 | 85 | IntegerType *int32Type = Type::getInt32Ty(module.getContext()); 86 | 87 | ConstantInt* arg0 = ConstantInt::getSigned(int32Type, blockId); 88 | ConstantInt* arg1 = ConstantInt::getSigned(int32Type, branchId); 89 | 90 | args.push_back((Value*)arg0); 91 | args.push_back((Value*)arg1); 92 | 93 | ArrayRef *arrayRef = new ArrayRef(args); 94 | 95 | CallInst::Create(module.getFunction("printBranch"), *arrayRef, "", i); 96 | printBranchTo = true; 97 | } 98 | } 99 | } 100 | } 101 | 102 | return true; 103 | } 104 | 105 | void Coverage::getAnalysisUsage(AnalysisUsage &AU __attribute__((unused))) const 106 | { 107 | return; 108 | } 109 | 110 | char Coverage::ID = 0; 111 | 112 | static const RegisterPass registration("coverage", "Prints Coverage Trace"); 113 | -------------------------------------------------------------------------------- /src/Coverage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COVERAGE_GUARD 2 | #define COVERGAGE_GUARD 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace llvm { 13 | } 14 | 15 | using namespace std; 16 | using namespace llvm; 17 | extern cl::opt ExcludedFunctionsFileName; 18 | 19 | class Coverage : public ModulePass { 20 | public: 21 | Coverage() : ModulePass(ID) {} 22 | 23 | void doInitialization(Module &module); 24 | 25 | bool runOnFunction(Module &module, Function &function); 26 | 27 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 28 | 29 | virtual bool runOnModule(Module &module); 30 | 31 | static char ID; // Pass identification, replacement for typeid 32 | 33 | private: 34 | set excludedFunctions; 35 | DebugInfoFinder debugInfo; 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/CreateCallDependency.cpp: -------------------------------------------------------------------------------- 1 | #include "CreateCallDependency.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace llvm; 14 | 15 | /** 16 | * Declaring call-main as an option to pass name of 17 | * main function to this pass. 18 | */ 19 | cl::opt CallMainName("call-main", cl::value_desc("name"), cl::desc("Name of main function"), cl::init("main")); 20 | 21 | bool CreateCallDependency::doInitialization(Module &M) { 22 | debugInfo.processModule(M); 23 | 24 | return true; 25 | } 26 | 27 | bool CreateCallDependency::runOnModule(Module &M) { 28 | doInitialization(M); 29 | 30 | for (Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { 31 | if (!f->isDeclaration()) { 32 | nameToCall[f->getName()] = f; 33 | } 34 | } 35 | 36 | findDependency(CallMainName); 37 | 38 | calls.insert(CallMainName); 39 | 40 | findUsedGlobalVar(M); 41 | 42 | doFinalization(); 43 | 44 | return true; 45 | } 46 | 47 | set CreateCallDependency::findCalledFunctions(string call) { 48 | set calledFunctions; 49 | Function *F = nameToCall[call]; 50 | 51 | for (Function::iterator b = F->begin(), be = F->end(); b != be; b++) { 52 | for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { 53 | if (CallInst *call = dyn_cast(i)) { 54 | if (Function* f = call->getCalledFunction()) { 55 | if (!f->isDeclaration()) { 56 | string calledFunction = f->getName(); 57 | calledFunctions.insert(calledFunction); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | return calledFunctions; 65 | } 66 | 67 | void CreateCallDependency::findDependency(string call) { 68 | set calledFunctions = findCalledFunctions(call); 69 | set::iterator cfIt; 70 | 71 | for (cfIt = calledFunctions.begin(); cfIt != calledFunctions.end(); ++cfIt) { 72 | string calledFunction = *cfIt; 73 | if (calls.find(calledFunction) == calls.end()) { 74 | calls.insert(calledFunction); 75 | findDependency(calledFunction); 76 | } 77 | } 78 | } 79 | 80 | void CreateCallDependency::findUsedGlobalVar(Module &M) { 81 | // 82 | // iterate through all global variables 83 | // 84 | for (Module::global_iterator it = M.global_begin(); it != M.global_end(); it++) { 85 | Value *value = it; 86 | // 87 | // iterate through all global variable usage 88 | // if global variable is used in one of the functions 89 | // in calls set, save global variable 90 | // into globalVars set. 91 | // 92 | if (GlobalVariable *global = dyn_cast(value)) { 93 | for (Value::use_iterator uit = global->use_begin(); uit != global->use_end(); uit++) { 94 | if (Instruction *inst = dyn_cast(*uit)) { 95 | Function *f = inst->getParent()->getParent(); 96 | string functionName = f->getName(); 97 | if (calls.find(functionName) != calls.end()) { 98 | globalVars.insert(global->getName()); 99 | } 100 | } 101 | } 102 | } 103 | } 104 | } 105 | 106 | void CreateCallDependency::getAnalysisUsage(AnalysisUsage &AU) const { 107 | AU.setPreservesAll(); 108 | } 109 | 110 | void CreateCallDependency::doFinalization() { 111 | set::iterator i; 112 | 113 | ofstream includeFile ("include.txt"); 114 | if (includeFile.is_open()) { 115 | for (i = calls.begin(); i != calls.end(); ++i) { 116 | includeFile << *i << "\n"; 117 | } 118 | includeFile.close(); 119 | } 120 | 121 | ofstream globalIncludeFile ("include_global.txt"); 122 | if (globalIncludeFile.is_open()) { 123 | for (i = globalVars.begin(); i != globalVars.end(); ++i) { 124 | globalIncludeFile << *i << "\n"; 125 | } 126 | globalIncludeFile.close(); 127 | } 128 | 129 | } 130 | 131 | char CreateCallDependency::ID = 0; 132 | 133 | static const RegisterPass registration("create-call-dependency", "Create call depepdency"); 134 | -------------------------------------------------------------------------------- /src/CreateCallDependency.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CREATE_CALL_DEPENDENCY 2 | #define CREATE_CALL_DEPENDENCY 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | using namespace llvm; 11 | using namespace std; 12 | 13 | class CreateCallDependency : public ModulePass { 14 | 15 | public: 16 | CreateCallDependency() : ModulePass(ID) {} 17 | 18 | bool doInitialization(Module &M); 19 | 20 | virtual bool runOnModule(Module &M); 21 | 22 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 23 | 24 | void findDependency(string call); 25 | 26 | set findCalledFunctions(string call); 27 | 28 | void findUsedGlobalVar(Module &M); 29 | 30 | void doFinalization(); 31 | 32 | static char ID; // Pass identification, replacement for typeid 33 | 34 | private: 35 | DebugInfoFinder debugInfo; 36 | 37 | set calls; 38 | 39 | set globalVars; 40 | 41 | map nameToCall; 42 | }; 43 | 44 | #endif // CREATE_CALL_DEPENDENCY 45 | -------------------------------------------------------------------------------- /src/CreateConfigFile.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CREATE_CONFIG_FILE_GUARD 2 | #define CREATE_CONFIG_FILE_GUARD 1 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace llvm { 11 | class GlobalVariable; 12 | class raw_fd_ostream; 13 | class Type; 14 | class Value; 15 | } 16 | 17 | using namespace std; 18 | using namespace llvm; 19 | 20 | typedef vector Variables; 21 | 22 | 23 | class CreateConfigFile : public ModulePass { 24 | 25 | public: 26 | CreateConfigFile() : ModulePass(ID) {} 27 | 28 | virtual bool runOnModule(Module &module); 29 | 30 | bool runOnFunction(Function &function, raw_fd_ostream &outfile, bool &first); 31 | 32 | bool doInitialization(Module &); 33 | 34 | void findFunctionCalls(Function &function, raw_fd_ostream &outfile, bool &first); 35 | 36 | void findGlobalVariables(Module &module, raw_fd_ostream &outfile, bool &first); 37 | 38 | void findLocalVariables(Function &function, raw_fd_ostream &outfile, bool &first); 39 | 40 | void findOperators(Function &function, raw_fd_ostream &outfile, bool &first); 41 | 42 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 43 | 44 | const map &getLocals(); 45 | 46 | static char ID; // Pass identification, replacement for typeid 47 | 48 | private: 49 | set excludedFunctions; 50 | 51 | set includedFunctions; 52 | 53 | set includedGlobalVars; 54 | 55 | set excludedLocalVars; 56 | 57 | set functionCalls; 58 | }; 59 | 60 | #endif // CREATE_CONFIG_FILE_GUARD 61 | -------------------------------------------------------------------------------- /src/CreateIDBitcode.cpp: -------------------------------------------------------------------------------- 1 | #include "CreateIDBitcode.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | using namespace llvm; 11 | 12 | bool CreateIDBitcode::runOnModule(Module &M) { 13 | 14 | for(Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { 15 | if (!f->isDeclaration()) { 16 | runOnFunction(*f); 17 | } 18 | } 19 | return true; 20 | } 21 | 22 | bool CreateIDBitcode::runOnFunction(Function &f) { 23 | 24 | for(Function::iterator b = f.begin(), be = f.end(); b != be; b++) { 25 | for(BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { 26 | Instruction *inst = i; 27 | LLVMContext& context = inst->getContext(); 28 | // convert inst id to string 29 | string instIdStr = static_cast( &(ostringstream() << instId) )->str(); 30 | MDNode* mdNode = MDNode::get(context, MDString::get(context, instIdStr)); 31 | // set inst id via metadata 32 | inst->setMetadata("corvette.inst.id", mdNode); 33 | // to retrieve metadata later 34 | // cast(inst->getMetadata("corvette.inst.id")->getOperand(0)->getString()); 35 | instId++; 36 | } 37 | } 38 | 39 | return false; 40 | } 41 | 42 | void CreateIDBitcode::getAnalysisUsage(AnalysisUsage &AU __attribute__((unused))) const { 43 | // no dependencies 44 | return; 45 | } 46 | 47 | int CreateIDBitcode::instId = 0; 48 | 49 | char CreateIDBitcode::ID = 0; 50 | 51 | static const RegisterPass registration("create-ids", "Create bitcode with ids"); 52 | -------------------------------------------------------------------------------- /src/CreateIDBitcode.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CREATE_ID_BITCODE 2 | #define CREATE_ID_BITCODE 3 | 4 | #include 5 | 6 | using namespace std; 7 | using namespace llvm; 8 | 9 | class CreateIDBitcode : public ModulePass { 10 | 11 | public: 12 | CreateIDBitcode() : ModulePass(ID) {} 13 | 14 | virtual bool runOnModule(Module &M); 15 | 16 | bool runOnFunction(Function &F); 17 | 18 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 19 | 20 | static int instId; // Instruction id 21 | 22 | static char ID; // Pass identification, replacement for typeid 23 | }; 24 | 25 | #endif // CREATE_ID_BITCODE 26 | -------------------------------------------------------------------------------- /src/CreateSearchFile.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CREATE_SEARCH_FILE_GUARD 2 | #define CREATE_SEARCH_FILE_GUARD 1 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace llvm { 12 | class GlobalVariable; 13 | class raw_fd_ostream; 14 | class Type; 15 | class Value; 16 | } 17 | 18 | using namespace std; 19 | using namespace llvm; 20 | extern cl::opt ExcludedFunctionsFileName; 21 | extern cl::opt IncludedFunctionsFileName; 22 | extern cl::opt IncludedGlobalVarsFileName; 23 | extern cl::opt ExcludedLocalVarsFileName; 24 | extern cl::opt ListOperators; 25 | extern cl::opt ListFunctions; 26 | extern cl::opt OnlyScalars; 27 | extern cl::opt OnlyArrays; 28 | extern cl::opt FileName; 29 | 30 | typedef vector Variables; 31 | 32 | 33 | class CreateSearchFile : public ModulePass { 34 | 35 | public: 36 | CreateSearchFile() : ModulePass(ID) {} 37 | 38 | virtual bool runOnModule(Module &module); 39 | 40 | bool runOnFunction(Function &function, raw_fd_ostream &outfile, bool &first); 41 | 42 | bool doInitialization(Module &); 43 | 44 | void findFunctionCalls(Function &function, raw_fd_ostream &outfile, bool &first); 45 | 46 | void findGlobalVariables(Module &module, raw_fd_ostream &outfile, bool &first); 47 | 48 | void findLocalVariables(Function &function, raw_fd_ostream &outfile, bool &first); 49 | 50 | void printLocal(Function &function, raw_fd_ostream &outfile, bool &first, string name, Type *type); 51 | 52 | void printGlobal(raw_fd_ostream &outfile, bool &first, string name, Type *type); 53 | 54 | void findOperators(Function &function, raw_fd_ostream &outfile, bool &first); 55 | 56 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 57 | 58 | const map &getLocals(); 59 | 60 | static char ID; // Pass identification, replacement for typeid 61 | 62 | private: 63 | set excludedFunctions; 64 | 65 | set includedFunctions; 66 | 67 | set includedGlobalVars; 68 | 69 | set excludedLocalVars; 70 | 71 | set functionCalls; 72 | }; 73 | 74 | #endif // CREATE_SEARCH_FILE_GUARD 75 | -------------------------------------------------------------------------------- /src/Debug.hpp: -------------------------------------------------------------------------------- 1 | #ifdef DEBUG 2 | #undef DEBUG 3 | #endif 4 | // #define DEBUG 1 5 | 6 | -------------------------------------------------------------------------------- /src/FuncStrChange.cpp: -------------------------------------------------------------------------------- 1 | #include "StrChange.hpp" 2 | #include "FuncStrChange.hpp" 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace llvm; 9 | 10 | FuncStrChange::FuncStrChange(string aClassification, string aTypes, int aField, string aSwit) : StrChange(aClassification, aTypes, aField) { 11 | swit = aSwit; 12 | } 13 | 14 | string FuncStrChange::getSwitch() { 15 | return swit; 16 | } 17 | -------------------------------------------------------------------------------- /src/FuncStrChange.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FUNC_STR_CHANGE_GUARD 2 | #define FUNC_STR_CHANGE_GUARD 1 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class FuncStrChange : public StrChange { 10 | public: 11 | FuncStrChange(string, string, int, string); 12 | ~FuncStrChange(); 13 | 14 | string getSwitch(); 15 | 16 | protected: 17 | string swit; 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/FunctionCalls.cpp: -------------------------------------------------------------------------------- 1 | #include "FunctionCalls.hpp" 2 | #include "FunctionChange.hpp" 3 | #include "ParseConfig.hpp" 4 | #include "Variables.hpp" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | using namespace llvm; 18 | 19 | 20 | void FunctionCalls::doInitialization(Module &module) { 21 | 22 | debugInfo.processModule(module); 23 | ParseConfig &parseConfig = getAnalysis(); 24 | changes = parseConfig.getChanges(); 25 | 26 | return; 27 | } 28 | 29 | 30 | bool FunctionCalls::runOnModule(Module &module) { 31 | errs() << "Replacing function calls\n"; 32 | doInitialization(module); 33 | 34 | vector::iterator it; 35 | for(it = changes[CALL].begin(); it != changes[CALL].end(); it++) { 36 | changeFunctionCall(module, *it); 37 | } 38 | return true; 39 | } 40 | 41 | 42 | CallInst* FunctionCalls::changeFunctionCall(Module &module, Change* change) { 43 | FunctionChange *funChange = (FunctionChange*)change; 44 | CallInst *oldCallInst = dyn_cast(funChange->getValue()); 45 | CallInst *newCallInst = NULL; 46 | string oldFunction = oldCallInst->getCalledFunction()->getName(); 47 | string newFunction = funChange->getSwitch(); 48 | 49 | // TODO: use the types vector to not assume signature 50 | Function *newCallee = module.getFunction(newFunction); 51 | if (newCallee) { 52 | errs() << "Changing function call from " << oldFunction << " to " << newFunction << "\n"; 53 | 54 | if (oldFunction != newFunction) { 55 | // retrieving original operand 56 | Value *oldOperand = oldCallInst->getOperand(0); 57 | 58 | // downcasting operand 59 | Type *fType = Type::getFloatTy(module.getContext()); 60 | FPTruncInst *newOperand = new FPTruncInst(oldOperand, fType, "", oldCallInst); 61 | 62 | // populating array of operands 63 | vector operands; 64 | operands.push_back(newOperand); 65 | ArrayRef *arrayRefOperands = new ArrayRef(operands); 66 | 67 | // creating the new CallInst 68 | newCallInst = CallInst::Create(newCallee, *arrayRefOperands, "newCall", oldCallInst); 69 | 70 | // casting result to double 71 | Type *dType = Type::getDoubleTy(module.getContext()); 72 | FPExtInst *result = new FPExtInst(newCallInst, dType, "", oldCallInst); 73 | 74 | // replacing all uses of call instruction 75 | oldCallInst->replaceAllUsesWith(result); 76 | 77 | // deleting old callInst 78 | oldCallInst->eraseFromParent(); 79 | 80 | errs() << "\tChange was successful\n"; 81 | } 82 | else { 83 | errs() << "\tNo change required\n"; 84 | } 85 | } 86 | else { 87 | errs() << "\tDid not find function " << newFunction << "\n"; 88 | } 89 | 90 | return newCallInst; 91 | } 92 | 93 | 94 | void FunctionCalls::getAnalysisUsage(AnalysisUsage &AU) const { 95 | AU.setPreservesAll(); 96 | AU.addRequired(); 97 | AU.addRequired(); 98 | } 99 | 100 | 101 | char FunctionCalls::ID = 0; 102 | static const RegisterPass registration("function-calls", "Replaces function calls"); 103 | -------------------------------------------------------------------------------- /src/FunctionCalls.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTION_CALLS_GUARD 2 | #define FUNCTION_CALLS_GUARD 1 3 | 4 | #include "ParseConfig.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace llvm { 10 | class CallInst; 11 | } 12 | 13 | using namespace std; 14 | using namespace llvm; 15 | 16 | class FunctionCalls : public ModulePass { 17 | 18 | public: 19 | FunctionCalls() : ModulePass(ID) {} 20 | 21 | void doInitialization(Module &module); 22 | 23 | CallInst* changeFunctionCall(Module &module, Change* change); 24 | 25 | //bool runOnFunction(Module &module, Function &function); 26 | 27 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 28 | 29 | virtual bool runOnModule(Module &module); 30 | 31 | static char ID; // Pass identification, replacement for typeid 32 | 33 | private: 34 | DebugInfoFinder debugInfo; 35 | 36 | map changes; 37 | 38 | }; 39 | 40 | #endif // FUNCTION_CALLS_GUARD 41 | -------------------------------------------------------------------------------- /src/FunctionChange.cpp: -------------------------------------------------------------------------------- 1 | #include "FunctionChange.hpp" 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace llvm; 8 | 9 | FunctionChange::FunctionChange(Types aType, Value* aValue, string aSwit) : Change(aType, aValue) { 10 | swit = aSwit; 11 | } 12 | 13 | string FunctionChange::getSwitch() { 14 | return swit; 15 | } 16 | -------------------------------------------------------------------------------- /src/FunctionChange.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTION_CHANGE_GUARD 2 | #define FUNCTION_CHANGE_GUARD 1 3 | 4 | #include "Change.hpp" 5 | #include 6 | #include 7 | 8 | namespace llvm { 9 | class Value; 10 | } 11 | 12 | using namespace llvm; 13 | using namespace std; 14 | 15 | typedef vector Types; 16 | 17 | class FunctionChange : public Change { 18 | public: 19 | FunctionChange(Types, Value*, string); 20 | ~FunctionChange(); 21 | 22 | string getSwitch(); 23 | 24 | protected: 25 | string swit; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/Instrument.cpp: -------------------------------------------------------------------------------- 1 | #include "Instrument.hpp" 2 | 3 | #include 4 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | void Instrument::doInitialization(Module &module) { 12 | debugInfo.processModule(module); 13 | 14 | ifstream inFile(ExcludedFunctionsFileName.c_str()); 15 | string name; 16 | 17 | if (!inFile) { 18 | errs() << "Unable to open " << ExcludedFunctionsFileName << '\n'; 19 | exit(1); 20 | } 21 | 22 | while(inFile >> name) { 23 | excludedFunctions.insert(name); 24 | } 25 | inFile.close(); 26 | 27 | return; 28 | } 29 | 30 | 31 | bool Instrument::runOnModule(Module &module) { 32 | doInitialization(module); 33 | 34 | // iterate through functions in module 35 | for(Module::iterator f = module.begin(), fe = module.end(); f != fe; f++) { 36 | runOnFunction(module, *f); 37 | } 38 | 39 | return true; 40 | } 41 | 42 | 43 | static void createCallInst(Module &module, Instruction *instruction, Type *type, string prefixName) { 44 | 45 | Function *callee = NULL; 46 | 47 | if (type) { 48 | unsigned int typeID = type->getTypeID(); 49 | 50 | switch(typeID) { 51 | case Type::FloatTyID: 52 | callee = module.getFunction(prefixName + "Float"); 53 | break; 54 | 55 | case Type::DoubleTyID: 56 | callee = module.getFunction(prefixName + "Double"); 57 | break; 58 | 59 | case Type::X86_FP80TyID: 60 | callee = module.getFunction(prefixName + "LongDouble"); 61 | break; 62 | } 63 | } 64 | else { 65 | callee = module.getFunction(prefixName); 66 | } 67 | 68 | 69 | if (callee) { 70 | CallInst::Create(callee, "", instruction); 71 | } 72 | 73 | return; 74 | } 75 | 76 | 77 | bool Instrument::runOnFunction(Module &module, Function &function) { 78 | 79 | if (! function.isDeclaration() && (excludedFunctions.find(function.getName()) == excludedFunctions.end())) { 80 | for(Function::iterator b = function.begin(), be = function.end(); b != be; b++) { 81 | for(BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { 82 | 83 | if (StoreInst *storeInst = dyn_cast(i)) { 84 | Type *type = storeInst->getOperand(0)->getType(); 85 | string prefixName = "incrementStoreInst"; 86 | createCallInst(module, i, type, prefixName); 87 | } 88 | 89 | if (LoadInst *loadInst = dyn_cast(i)) { 90 | Value *pointerOperand = loadInst->getPointerOperand(); 91 | PointerType* pointerType = dyn_cast(pointerOperand->getType()); 92 | Type *type = pointerType->getElementType(); 93 | string prefixName = "incrementLoadInst"; 94 | createCallInst(module, i, type, prefixName); 95 | } 96 | 97 | if (BinaryOperator *binOp = dyn_cast(i)) { 98 | Type *type = binOp->getOperand(0)->getType(); 99 | switch(binOp->getOpcode()) { 100 | case Instruction::FAdd: 101 | case Instruction::FSub: 102 | case Instruction::FMul: 103 | case Instruction::FDiv: { 104 | string prefixName = "incrementArithOpInst"; 105 | createCallInst(module, i, type, prefixName); 106 | break; 107 | } 108 | default: 109 | // do nothing 110 | break; 111 | } 112 | } 113 | 114 | if (FCmpInst *cmpOp = dyn_cast(i)) { 115 | Type *type = cmpOp->getOperand(0)->getType(); 116 | string prefixName = "incrementCmpOpInst"; 117 | createCallInst(module, i, type, prefixName); 118 | } 119 | 120 | if (dyn_cast(i)) { 121 | string prefixName = "incrementFPTruncInst"; 122 | createCallInst(module, i, NULL, prefixName); 123 | } 124 | 125 | if (dyn_cast(i)) { 126 | string prefixName = "incrementFPExtInst"; 127 | createCallInst(module, i, NULL, prefixName); 128 | } 129 | 130 | } // for BasicBlock 131 | } // for Function 132 | } // if 133 | 134 | if (function.getName() == "main") { 135 | for(Function::iterator b = function.begin(), be = function.end(); b != be; b++) { 136 | for(BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { 137 | if (ReturnInst *returnInst = dyn_cast(i)) { 138 | if (function.getName() == "main") { 139 | if (Function *callee = module.getFunction("printCounters")) { 140 | CallInst::Create(callee, "", returnInst); 141 | } 142 | } 143 | } 144 | 145 | } 146 | } 147 | 148 | } 149 | return true; 150 | } 151 | 152 | 153 | void Instrument::getAnalysisUsage(AnalysisUsage &AU __attribute__((unused))) const { 154 | return; 155 | } 156 | 157 | 158 | char Instrument::ID = 0; 159 | static const RegisterPass registration("instrument", "Instruments FP Stores, Loads, Arithmetic Operators and Comparison Operators"); 160 | -------------------------------------------------------------------------------- /src/Instrument.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INSTRUMENT_GUARD 2 | #define INSTRUMENT_GUARD 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace llvm { 13 | class Value; 14 | class BinaryOperator; 15 | class FCmpInst; 16 | class Type; 17 | } 18 | 19 | using namespace std; 20 | using namespace llvm; 21 | extern cl::opt ExcludedFunctionsFileName; 22 | 23 | 24 | class Instrument : public ModulePass { 25 | public: 26 | Instrument() : ModulePass(ID) {} 27 | 28 | void doInitialization(Module &module); 29 | 30 | bool runOnFunction(Module &module, Function &function); 31 | 32 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 33 | 34 | virtual bool runOnModule(Module &module); 35 | 36 | static char ID; // Pass identification, replacement for typeid 37 | 38 | private: 39 | set excludedFunctions; 40 | 41 | DebugInfoFinder debugInfo; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/MeasureMetric.cpp: -------------------------------------------------------------------------------- 1 | #include "MeasureMetric.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | void MeasureMetric::doInitialization(Module &M) { 15 | debugInfo.processModule(M); 16 | castInstCount = 0; 17 | score = 0; 18 | arithOp["float"] = 0; 19 | arithOp["double"] = 0; 20 | arithOp["longdouble"] = 0; 21 | cmpOp["float"] = 0; 22 | cmpOp["double"] = 0; 23 | cmpOp["longdouble"] = 0; 24 | loadOp["float"] = 0; 25 | loadOp["double"] = 0; 26 | loadOp["longdouble"] = 0; 27 | storeOp["float"] = 0; 28 | storeOp["double"] = 0; 29 | storeOp["longdouble"] = 0; 30 | 31 | return; 32 | } 33 | 34 | bool MeasureMetric::runOnModule(Module &M) { 35 | doInitialization(M); 36 | 37 | for(Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { 38 | if (!f->isDeclaration()) { 39 | runOnFunction(*f); 40 | } 41 | } 42 | 43 | doFinalization(); 44 | 45 | return false; 46 | } 47 | 48 | bool MeasureMetric::runOnFunction(Function &F) { 49 | for (Function::iterator b = F.begin(), be = F.end(); b != be; b++) { 50 | for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { 51 | Instruction *inst = i; 52 | if (dyn_cast(inst)) { 53 | castInstCount++; 54 | } else if (FCmpInst* target = dyn_cast(inst)) { 55 | Value *val1 = target->getOperand(0); 56 | increaseCounter(val1->getType(), cmpOp); 57 | } else if (BinaryOperator *target = dyn_cast(inst)) { 58 | Value *val1 = target->getOperand(0); 59 | increaseCounter(val1->getType(), arithOp); 60 | } else if (LoadInst *target = dyn_cast(inst)) { 61 | Value *val1 = target->getPointerOperand(); 62 | PointerType* pointerType = (PointerType*) val1->getType(); 63 | increaseCounter(pointerType->getElementType(), loadOp); 64 | } else if (StoreInst* target = dyn_cast(inst)) { 65 | Value *val1 = target->getOperand(0); 66 | increaseCounter(val1->getType(), storeOp); 67 | } 68 | } 69 | } 70 | 71 | return false; 72 | } 73 | 74 | void MeasureMetric::increaseCounter(Type* type, map &counter) { 75 | if (type->isFloatTy()) { 76 | counter["float"]++; 77 | score = score + 32; 78 | } else if (type->isDoubleTy()) { 79 | counter["double"]++; 80 | score = score + 64; 81 | } else if (type->isX86_FP80Ty()) { 82 | counter["longdouble"]++; 83 | score = score + 80; 84 | } 85 | 86 | return; 87 | } 88 | 89 | void MeasureMetric::printCounter(map &counter) { 90 | errs() << "\t float: " << counter["float"] << "\n"; 91 | errs() << "\t double: " << counter["double"] << "\n"; 92 | errs() << "\t X86_FP80: " << counter["longdouble"] << "\n"; 93 | 94 | return; 95 | } 96 | 97 | void MeasureMetric::doFinalization() { 98 | errs() << "The number of casting instruction: " << castInstCount << "\n"; 99 | errs() << "The number of arithmetic operations\n"; 100 | printCounter(arithOp); 101 | errs() << "The number of comparison operations\n"; 102 | printCounter(cmpOp); 103 | errs() << "The number of load instructions\n"; 104 | printCounter(loadOp); 105 | errs() << "The number of store instructions\n"; 106 | printCounter(storeOp); 107 | ofstream scoreFile; 108 | scoreFile.open("score.cov", ios_base::app); 109 | scoreFile << "#score\n"; 110 | scoreFile << score << "\n"; 111 | scoreFile.close(); 112 | 113 | return; 114 | } 115 | 116 | void MeasureMetric::getAnalysisUsage(AnalysisUsage &AU) const { 117 | AU.setPreservesAll(); 118 | } 119 | 120 | char MeasureMetric::ID = 0; 121 | 122 | static const RegisterPass registration("measure-metric", "Print software metric information"); 123 | -------------------------------------------------------------------------------- /src/MeasureMetric.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MEASURE_METRIC_GUARD 2 | #define MEASURE_METRIC_GUARD 1 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace llvm { 12 | class Type; 13 | } 14 | 15 | using namespace std; 16 | using namespace llvm; 17 | 18 | class MeasureMetric : public ModulePass { 19 | 20 | public: 21 | MeasureMetric() : ModulePass(ID) {} 22 | 23 | void doInitialization(Module &M); 24 | 25 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 26 | 27 | virtual bool runOnModule(Module &M); 28 | 29 | bool runOnFunction(Function &F); 30 | 31 | void increaseCounter(Type* type, map &counter); 32 | 33 | void printCounter(map &counter); 34 | 35 | void doFinalization(); 36 | 37 | static char ID; // Pass identification, replacement for typeid 38 | 39 | private: 40 | DebugInfoFinder debugInfo; 41 | 42 | int score; // total score 43 | 44 | int castInstCount; // Counter of cast isntructions 45 | 46 | map arithOp; // Counter of airthmetic operations 47 | 48 | map cmpOp; // Counter of comparision operations 49 | 50 | map loadOp; // Counter of load instructions 51 | 52 | map storeOp; // Counter of store instructions 53 | 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/Operators.cpp: -------------------------------------------------------------------------------- 1 | #include "Operators.hpp" 2 | #include "ParseConfig.hpp" 3 | 4 | #include 5 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 6 | #include 7 | 8 | void Operators::doInitialization(Module &module) { 9 | 10 | debugInfo.processModule(module); 11 | 12 | ParseConfig &parseConfig = getAnalysis(); 13 | changes = parseConfig.getChanges(); 14 | 15 | return; 16 | } 17 | 18 | bool Operators::runOnModule(Module &module) { 19 | 20 | doInitialization(module); 21 | 22 | // iterate through operator set 23 | 24 | vector::iterator it; 25 | for (it = changes[OP].begin(); it != changes[OP].end(); it++) { 26 | Change *change = *it; 27 | Value *target = change->getValue(); 28 | Type *new_type = change->getType().at(0); 29 | 30 | if (target) { 31 | if (FCmpInst* old_target = dyn_cast(target)) { 32 | changeFCmpInst(old_target, new_type); 33 | } else if (BinaryOperator* old_target = dyn_cast(target)) { 34 | changeBinaryOperator(old_target, new_type); 35 | } 36 | } 37 | } 38 | 39 | return true; 40 | } 41 | 42 | void Operators::changeBinaryOperator(BinaryOperator* old_target, Type* new_type) { 43 | Value *val_1 = old_target->getOperand(0); 44 | Value *val_2 = old_target->getOperand(1); 45 | Type* old_type = val_1->getType(); 46 | 47 | errs() << "Changing the precision of operator \"" << old_target->getOpcodeName() << "\" from " << *old_type << " to " << *new_type << ".\n"; 48 | 49 | if (old_type->getTypeID() != new_type->getTypeID()) { 50 | if (new_type->getTypeID() > old_type->getTypeID()) { 51 | FPExtInst *ext_1 = new FPExtInst(val_1, new_type, "", old_target); 52 | FPExtInst *ext_2 = new FPExtInst(val_2, new_type, "", old_target); 53 | BinaryOperator* new_target = BinaryOperator::Create(old_target->getOpcode(), ext_1, ext_2, "", old_target); 54 | FPTruncInst *trunc = new FPTruncInst(new_target, old_type, "", old_target); 55 | old_target->replaceAllUsesWith(trunc); 56 | } else { 57 | FPTruncInst *trunc_1 = new FPTruncInst(val_1, new_type, "", old_target); 58 | FPTruncInst *trunc_2 = new FPTruncInst(val_2, new_type, "", old_target); 59 | BinaryOperator* new_target = BinaryOperator::Create(old_target->getOpcode(), trunc_1, trunc_2, "", old_target); 60 | FPExtInst *ext = new FPExtInst(new_target, old_type, "", old_target); 61 | old_target->replaceAllUsesWith(ext); 62 | } 63 | old_target->eraseFromParent(); 64 | } else { 65 | errs() << "\tNo changes required.\n"; 66 | } 67 | 68 | return; 69 | } 70 | 71 | void Operators::changeFCmpInst(FCmpInst* old_target, Type* new_type) { 72 | Value *val_1 = old_target->getOperand(0); 73 | Value *val_2 = old_target->getOperand(1); 74 | Type* old_type = val_1->getType(); 75 | 76 | errs() << "Changing the precision of operator \"" << old_target->getOpcodeName() << "\" from " << *old_type << " to " << *new_type << ".\n"; 77 | 78 | if (old_type->getTypeID() != new_type->getTypeID()) { 79 | if (new_type->getTypeID() > old_type->getTypeID()) { 80 | FPExtInst *ext_1 = new FPExtInst(val_1, new_type, "", old_target); 81 | FPExtInst *ext_2 = new FPExtInst(val_2, new_type, "", old_target); 82 | FCmpInst* new_target = new FCmpInst(old_target, old_target->getPredicate(), ext_1, ext_2, ""); 83 | old_target->replaceAllUsesWith(new_target); 84 | } else { 85 | FPTruncInst *trunc_1 = new FPTruncInst(val_1, new_type, "", old_target); 86 | FPTruncInst *trunc_2 = new FPTruncInst(val_2, new_type, "", old_target); 87 | FCmpInst* new_target = new FCmpInst(old_target, old_target->getPredicate(), trunc_1, trunc_2, ""); 88 | old_target->replaceAllUsesWith(new_target); 89 | } 90 | old_target->eraseFromParent(); 91 | } else { 92 | errs() << "\tNo changes required.\n"; 93 | } 94 | 95 | return; 96 | } 97 | 98 | void Operators::getAnalysisUsage(AnalysisUsage &AU) const { 99 | AU.addRequired(); 100 | return; 101 | } 102 | 103 | char Operators::ID = 0; 104 | static const RegisterPass registration("operators", "Change the precision of operators"); 105 | -------------------------------------------------------------------------------- /src/Operators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef OPERATORS_GUARD 2 | #define OPERATORS_GUARD 1 3 | 4 | #include "ParseConfig.hpp" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace llvm { 15 | class Value; 16 | class BinaryOperator; 17 | class FCmpInst; 18 | class Type; 19 | } 20 | 21 | using namespace std; 22 | using namespace llvm; 23 | 24 | class Operators : public ModulePass { 25 | 26 | public: 27 | Operators() : ModulePass(ID) {} 28 | 29 | void doInitialization(Module &module); 30 | 31 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 32 | 33 | virtual bool runOnModule(Module &module); 34 | 35 | static char ID; // Pass identification, replacement for typeid 36 | 37 | private: 38 | void changeBinaryOperator(BinaryOperator* old_target, Type* new_type); 39 | 40 | void changeFCmpInst(FCmpInst* old_target, Type* new_type); 41 | 42 | DebugInfoFinder debugInfo; 43 | 44 | map changes; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/ParseConfig.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PARSE_CONFIG 2 | #define PARSE_CONFIG 3 | 4 | #include "Change.hpp" 5 | #include "StrChange.hpp" 6 | #include "config_parser.hpp" 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | using namespace llvm; 16 | 17 | typedef vector Changes; 18 | enum ChangeType {GLOBALVAR, LOCALVAR, OP, CALL}; 19 | 20 | 21 | class ParseConfig : public ModulePass { 22 | 23 | public: 24 | ParseConfig() : ModulePass(ID) {} 25 | 26 | /* 27 | * Get the set of changes. 28 | * 29 | * This maps each of the four objects - globalVar, 30 | * localVar, op and call - to the set of changes. 31 | */ 32 | map& getChanges(); 33 | 34 | bool doInitialization(Module &M); 35 | 36 | virtual bool runOnModule(Module &M); 37 | 38 | bool runOnFunction(Function &f); 39 | 40 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 41 | 42 | static char ID; // Pass identification, replacement for typeid 43 | 44 | private: 45 | DebugInfoFinder debugInfo; 46 | 47 | void updateChanges(string, Value*, LLVMContext&); 48 | 49 | static Value* findAlloca(Value*, Function*); 50 | 51 | map types; 52 | 53 | map changes; 54 | 55 | }; 56 | 57 | #endif // PARSE_CONFIG 58 | -------------------------------------------------------------------------------- /src/PrintFunctionNames.cpp: -------------------------------------------------------------------------------- 1 | #include "PrintFunctionNames.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace llvm; 14 | 15 | 16 | bool PrintFunctionNames::runOnModule(Module &M) { 17 | 18 | errs() << "Pass PrintFunctionNames\n"; 19 | 20 | // iterating through functions 21 | for(Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { 22 | 23 | if (!f->isDeclaration()) { 24 | // finding and printing file information 25 | BasicBlock &block = f->getEntryBlock(); 26 | Instruction &inst = block.front(); 27 | 28 | if (MDNode *node = inst.getMetadata("dbg")) { 29 | DILocation loc(node); 30 | errs() << "File name: " << loc.getFilename() << "\t"; 31 | } 32 | } 33 | 34 | // finding and printing function informatonion 35 | errs() << "Function name: " << f->getName() << "\n"; 36 | } 37 | 38 | return false; 39 | } 40 | 41 | 42 | void PrintFunctionNames::getAnalysisUsage(AnalysisUsage &AU) const { 43 | AU.setPreservesAll(); 44 | } 45 | 46 | 47 | char PrintFunctionNames::ID = 0; 48 | static const RegisterPass registration("print-names", "Printing function names"); 49 | -------------------------------------------------------------------------------- /src/PrintFunctionNames.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PRINT_FUNCTION_NAMES_GUARD 2 | #define PRINT_FUNCTION_NAMES_GUARD 1 3 | 4 | #include 5 | 6 | using namespace std; 7 | using namespace llvm; 8 | 9 | class PrintFunctionNames : public ModulePass { 10 | 11 | public: 12 | PrintFunctionNames() : ModulePass(ID) {} 13 | 14 | virtual bool runOnModule(Module &M); 15 | 16 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 17 | 18 | static char ID; // Pass identification, replacement for typeid 19 | 20 | }; 21 | 22 | #endif // PRINT_FUNCTION_NAMES_GUARD 23 | -------------------------------------------------------------------------------- /src/PrintVariableNames.cpp: -------------------------------------------------------------------------------- 1 | #include "PrintVariableNames.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace llvm; 15 | 16 | bool PrintVariableNames::runOnFunction(Function &F) { 17 | errs() << F.getName() << "\n"; 18 | 19 | // print all symbols 20 | ValueSymbolTable &S = F.getValueSymbolTable(); 21 | for (ValueSymbolTable::iterator v = S.begin(), ve = S.end(); v != ve; v++) { 22 | errs() << "\tvar: " << v->getKey() << "\n"; 23 | } 24 | 25 | BasicBlock &B = F.getEntryBlock(); 26 | for (BasicBlock::iterator i = B.begin(), ie = B.end(); i != ie; i++) { 27 | Instruction *inst = i; 28 | // errs () << "\ttype: " << inst->getOpcodeName() << "\n"; 29 | if (AllocaInst::classof(inst)) { 30 | AllocaInst *ainst = (AllocaInst *) inst; 31 | Type *type = ainst->getAllocatedType(); 32 | errs () << "\talloca: " << ainst->getName() << type->getTypeID() << "\n"; 33 | } else if (LoadInst::classof(inst)) { 34 | LoadInst *linst = (LoadInst *) inst; 35 | errs () << "\tload: " << linst->getPointerOperand()->getName() << "\n"; 36 | } 37 | } 38 | 39 | return false; 40 | } 41 | 42 | void PrintVariableNames::getAnalysisUsage(AnalysisUsage &AU) const { 43 | AU.setPreservesAll(); 44 | } 45 | 46 | char PrintVariableNames::ID = 1; 47 | static const RegisterPass registration("print-vars", "Printing variable names"); 48 | 49 | -------------------------------------------------------------------------------- /src/PrintVariableNames.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PRINT_VARIABLE_NAMES_GUARD 2 | #define PRINT_VARIABLE_NAMES_GUARD 1 3 | 4 | #include 5 | 6 | using namespace std; 7 | using namespace llvm; 8 | 9 | class PrintVariableNames : public FunctionPass { 10 | 11 | public: 12 | PrintVariableNames() : FunctionPass(ID) {} 13 | 14 | virtual bool runOnFunction(Function &F); 15 | 16 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 17 | 18 | static char ID; // Pass identification, replacement for typeid 19 | 20 | }; 21 | 22 | #endif // PRINT_VARIABLE_NAMES_GUARD 23 | -------------------------------------------------------------------------------- /src/RemoveDeadCasting.cpp: -------------------------------------------------------------------------------- 1 | #include "RemoveDeadCasting.hpp" 2 | 3 | #include 4 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | void RemoveDeadCasting::doInitialization(Module &M) { 11 | debugInfo.processModule(M); 12 | 13 | ifstream inFile(ExcludedFunctionsFileName.c_str()); 14 | string name; 15 | 16 | if (!inFile) { 17 | errs() << "Unable to open " << ExcludedFunctionsFileName << '\n'; 18 | exit(1); 19 | } 20 | 21 | while(inFile >> name) { 22 | excludedFunctions.insert(name); 23 | } 24 | inFile.close(); 25 | 26 | inFile.open (IncludedFunctionsFileName.c_str(), ifstream::in); 27 | if (!inFile) { 28 | errs() << "Unable to open " << IncludedFunctionsFileName << '\n'; 29 | exit(1); 30 | } 31 | 32 | while(inFile >> name) { 33 | includedFunctions.insert(name); 34 | } 35 | inFile.close(); 36 | 37 | return; 38 | } 39 | 40 | 41 | bool RemoveDeadCasting::runOnModule(Module &M) { 42 | doInitialization(M); 43 | 44 | errs() << "Running RemoveDeadCastings\n"; 45 | for (Module::iterator f = M.begin(), fe = M.end(); f != fe; f++) { 46 | if (!f->isDeclaration()) { 47 | runOnFunction(*f); 48 | } 49 | } 50 | errs() << "Done!\n"; 51 | 52 | return false; 53 | } 54 | 55 | // optimize the following pattern 56 | // inst0: old_type r1 57 | // inst1: r2 = (new_type) r1 58 | // inst2: r3 = (old_type) r2 59 | // if r2 is only used for casting 60 | // then remove inst1 and inst2, and 61 | // replace all uses of r3 with r1 62 | bool RemoveDeadCasting::runOnFunction(Function &F) { 63 | string name = F.getName(); 64 | 65 | if (! F.isDeclaration() && (includedFunctions.find(name) != includedFunctions.end()) && (excludedFunctions.find(name) == excludedFunctions.end())) { 66 | errs() << "=== Exploring function: " << F.getName() << "\n"; 67 | list dead_cast; 68 | for (Function::iterator b = F.begin(), be = F.end(); b != be; b++) { 69 | for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { 70 | Instruction *inst = i; 71 | if (CastInst* r2 = dyn_cast(inst)) { 72 | Value *r1 = r2->getOperand(0); 73 | Type* old_type = r1->getType(); 74 | 75 | if (old_type->getTypeID() == Type::FloatTyID || 76 | old_type->getTypeID() == Type::DoubleTyID || 77 | old_type->getTypeID() == Type::X86_FP80TyID) 78 | { 79 | bool use_only_for_cast = true; 80 | for (Value::use_iterator use = r2->use_begin(); use != r2->use_end(); use++) { 81 | if (CastInst* r3 = dyn_cast(*use)) { 82 | Type* new_type = r3->getType(); 83 | if (new_type->getTypeID() == old_type->getTypeID()) { 84 | // replace uses of r3 with r1 85 | r3->replaceAllUsesWith(r1); 86 | // remove r3 = (old_type) r2 87 | r3->eraseFromParent(); 88 | } else { 89 | use_only_for_cast = false; 90 | } 91 | } else { 92 | use_only_for_cast = false; 93 | } 94 | } 95 | 96 | if (use_only_for_cast) { 97 | dead_cast.push_back(r2); 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | for (list::iterator i = dead_cast.begin(); i != dead_cast.end(); i++) { 105 | Instruction *inst = *i; 106 | inst->eraseFromParent(); 107 | } 108 | } 109 | return false; 110 | } 111 | 112 | 113 | void RemoveDeadCasting::getAnalysisUsage(AnalysisUsage &AU __attribute__((unused))) const { 114 | // no dependencies 115 | return; 116 | } 117 | 118 | char RemoveDeadCasting::ID = 0; 119 | static const RegisterPass registration("remove-dead-casting", "Remove casting that is not used"); 120 | -------------------------------------------------------------------------------- /src/RemoveDeadCasting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REMOVE_DEAD_CASTING_GUARD 2 | #define REMOVE_DEAD_CASTING_GUARD 1 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace llvm { 11 | class Value; 12 | } 13 | 14 | using namespace std; 15 | using namespace llvm; 16 | 17 | extern cl::opt ExcludedFunctionsFileName; 18 | extern cl::opt IncludedFunctionsFileName; 19 | 20 | 21 | class RemoveDeadCasting : public ModulePass { 22 | 23 | public: 24 | RemoveDeadCasting() : ModulePass(ID) {} 25 | 26 | void doInitialization(Module &M); 27 | 28 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 29 | 30 | virtual bool runOnModule(Module &M); 31 | 32 | bool runOnFunction(Function &F); 33 | 34 | static char ID; // Pass identification, replacement for typeid 35 | 36 | private: 37 | DebugInfoFinder debugInfo; 38 | 39 | set excludedFunctions; 40 | 41 | set includedFunctions; 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/SConscript: -------------------------------------------------------------------------------- 1 | import SCons.Warnings 2 | from distutils.version import StrictVersion 3 | 4 | Import('env') 5 | 6 | env = env.Clone() 7 | 8 | def llvm_version(context): 9 | context.Message('Checking LLVM version ... ') 10 | succeeded, output = context.TryAction('$LLVM_CONFIG --version >$TARGET') 11 | if succeeded: 12 | result = output.rstrip('\n') 13 | context.env['llvm_version'] = result 14 | context.Result(result) 15 | return result 16 | else: 17 | context.Result('failed') 18 | context.env.Exit(1) 19 | 20 | def llvm_bindir(context): 21 | context.Message('Checking LLVM executables ... ') 22 | succeeded, output = context.TryAction('$LLVM_CONFIG --bindir >$TARGET') 23 | if succeeded: 24 | output = output.rstrip() 25 | context.env.PrependENVPath('PATH', output) 26 | context.Result(output) 27 | return output 28 | else: 29 | context.Result('failed') 30 | context.env.Exit(1) 31 | 32 | conf = Configure(env, custom_tests={ 33 | 'LLVMVersion': llvm_version, 34 | 'LLVMBinDir': llvm_bindir, 35 | }) 36 | 37 | conf.LLVMVersion() 38 | conf.LLVMBinDir() 39 | env = conf.Finish() 40 | 41 | #llvm_version = StrictVersion(env['llvm_version']) 42 | #llvm_require = '3.0' 43 | #if llvm_version < llvm_require: 44 | # SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, 'LLVM %s too old; need at least version %s' % (llvm_version, llvm_require)) 45 | # Return() 46 | 47 | 48 | ######################################################################## 49 | # 50 | # LLVM plugin building 51 | # 52 | 53 | env.AppendUnique( 54 | #SHLINKFLAGS='-Wl,--no-undefined', 55 | SHLINKFLAGS='-Wl', 56 | LIBS='LLVM-$llvm_version', 57 | ) 58 | env.MergeFlags('!llvm-config --cxxflags --ldflags') 59 | 60 | plugin = env.SharedLibrary( 61 | 'Passes', 62 | [ 63 | 'AdjustOperators.cpp', 64 | 'Change.cpp', 65 | 'FunctionChange.cpp', 66 | 'Coverage.cpp', 67 | 'CreateCallDependency.cpp', 68 | 'CreateConfigFile.cpp', 69 | 'CreateIDBitcode.cpp', 70 | 'CreateSearchFile.cpp', 71 | 'FunctionCalls.cpp', 72 | 'Instrument.cpp', 73 | 'MeasureMetric.cpp', 74 | 'Operators.cpp', 75 | 'ParseConfig.cpp', 76 | 'PrintFunctionNames.cpp', 77 | 'PrintVariableNames.cpp', 78 | 'RemoveDeadCasting.cpp', 79 | 'Structs.cpp', 80 | 'StrChange.cpp', 81 | 'FuncStrChange.cpp', 82 | 'Transformer.cpp', 83 | 'Variables.cpp', 84 | 'config_parser.cpp', 85 | 'lib/vjson/json.cpp', 86 | 'lib/vjson/block_allocator.cpp' 87 | ], 88 | INCPREFIX='-isystem ', 89 | SHLIBPREFIX=None, 90 | ) 91 | 92 | Default(plugin) 93 | 94 | 95 | ######################################################################## 96 | # 97 | # full test suite starting from C source code 98 | # 99 | 100 | SConscript( 101 | dirs=[ 102 | 'tests', 103 | ], 104 | exports='env', 105 | ) 106 | -------------------------------------------------------------------------------- /src/StrChange.cpp: -------------------------------------------------------------------------------- 1 | #include "StrChange.hpp" 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace llvm; 8 | 9 | StrChange::StrChange(string aClassification, string aTypes, int aField) { 10 | classification = aClassification; 11 | types = aTypes; 12 | field = aField; 13 | } 14 | 15 | string StrChange::getClassification() { 16 | return classification; 17 | } 18 | 19 | string StrChange::getTypes() { 20 | return types; 21 | } 22 | 23 | int StrChange::getField() { 24 | return field; 25 | } 26 | -------------------------------------------------------------------------------- /src/StrChange.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STRCHANGE_GUARD 2 | #define STRCHANGE_GUARD 1 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class StrChange { 10 | public: 11 | StrChange(string, string, int); 12 | ~StrChange(); 13 | 14 | string getClassification(); 15 | 16 | string getTypes(); 17 | 18 | int getField(); 19 | 20 | protected: 21 | string classification; 22 | string types; 23 | int field; 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/Structs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STRUCTS_GUARD 2 | #define STRUCTS_GUARD 1 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace llvm { 11 | class StructType; 12 | } 13 | 14 | using namespace std; 15 | using namespace llvm; 16 | 17 | class Structs : public ModulePass { 18 | 19 | public: 20 | Structs() : ModulePass(ID) {} 21 | 22 | void doInitialization(Module &module); 23 | 24 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 25 | 26 | virtual bool runOnModule(Module &module); 27 | 28 | bool runOnFunction(Function &function); 29 | 30 | void printGlobals(Module &module); 31 | 32 | void printLocals(Function &function); 33 | 34 | void printStructFields(StructType *structType); 35 | 36 | void changeLocal(Value *value, LLVMContext& context); 37 | 38 | static char ID; // Pass identification, replacement for typeid 39 | 40 | private: 41 | DebugInfoFinder debugInfo; 42 | 43 | vector locals; 44 | 45 | vector globals; 46 | }; 47 | 48 | #endif // STRUCTS_GUARD 49 | 50 | -------------------------------------------------------------------------------- /src/Transformer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TRANSFORMER_GUARD 2 | #define TRANSFORMER_GUARD 1 3 | 4 | #include 5 | #include "Debug.hpp" 6 | 7 | namespace llvm { 8 | class Value; 9 | class ConstantInt; 10 | } 11 | 12 | using namespace std; 13 | using namespace llvm; 14 | 15 | class Transformer { 16 | public: 17 | static bool transform(value_use_iterator, Value*, Value*, Type*, Type*, unsigned); 18 | static bool transform(LoadInst&, Value*, Value*, Type*, Type*, unsigned); 19 | static bool transform(StoreInst&, Value*, Value*, Type*, Type*, unsigned); 20 | static bool transform(BitCastInst&, Value*, Value*, Type*, Type*, unsigned); 21 | static bool transform(GetElementPtrInst&, Value*, Value*, Type*, Type*, unsigned); 22 | static bool transform(CallInst&, Value*, Value*, Type*, Type*, unsigned); 23 | static ConstantInt* getInt32(int n); 24 | static ConstantInt* getInt64(int n); 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/Variables.hpp: -------------------------------------------------------------------------------- 1 | #ifndef VARIABLES_GUARD 2 | #define VARIABLES_GUARD 1 3 | 4 | #include "ParseConfig.hpp" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace llvm { 13 | class AllocaInst; 14 | class ConstantInt; 15 | class Value; 16 | } 17 | 18 | using namespace std; 19 | using namespace llvm; 20 | 21 | class Variables : public ModulePass { 22 | 23 | public: 24 | Variables() : ModulePass(ID) {} 25 | 26 | void doInitialization(Module &module); 27 | 28 | void changeGlobal(Change* change, Module &module); 29 | 30 | AllocaInst* changeLocal(Change* change); 31 | 32 | AllocaInst* changeLocal(Value* value, Type* type); 33 | 34 | AllocaInst* changeLocal(Value* value, ArrayType* type); 35 | 36 | AllocaInst* changeLocal(Value* value, PointerType* type); 37 | 38 | AllocaInst* changeLocal(Value* value, StructType* type/*, int field*/); 39 | 40 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; 41 | 42 | virtual bool runOnModule(Module &module); 43 | 44 | static unsigned getAlignment(Type* type); 45 | 46 | static ConstantInt* getInt32(int n); 47 | 48 | static ConstantInt* getInt64(int n); 49 | 50 | static ConstantInt* getSizeInBits(Type *type); 51 | 52 | static ConstantInt* getAlignmentInBits(Type *type); 53 | 54 | static MDNode* getTypeMetadata(Module& module, DIVariable &oldDIVar, Type* newType); 55 | 56 | static void updateMetadata(Module& module, Value* oldTarget, Value* newTarget, Type* newType); 57 | 58 | static char ID; // Pass identification, replacement for typeid 59 | 60 | private: 61 | DebugInfoFinder debugInfo; 62 | 63 | map changes; 64 | }; 65 | 66 | #endif // VARIABLES_GUARD 67 | 68 | -------------------------------------------------------------------------------- /src/branches.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | void printBranch(int blockId, int branchId) 6 | { 7 | FILE* file = fopen("coverage.cov", "a"); 8 | fprintf(file, "Reaching branch %d ", branchId); 9 | fclose(file); 10 | } 11 | 12 | void printBranchTo(int blockId) 13 | { 14 | FILE* file = fopen("coverage.cov", "a"); 15 | fprintf(file, "lead to block %d\n", blockId); 16 | fclose(file); 17 | } 18 | -------------------------------------------------------------------------------- /src/config_parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONFIGPARSER_GUARD 2 | #define CONFIGPARSER_GUARD 1 3 | 4 | #include "vjson/json.h" 5 | #include "vjson/block_allocator.h" 6 | #include 7 | #include 8 | #include 9 | #include "StrChange.hpp" 10 | #include "FuncStrChange.hpp" 11 | 12 | using namespace std; 13 | 14 | map parse_config(const char *filename); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/counters.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int counterStoreInstFloat = 0; 5 | int counterStoreInstDouble = 0; 6 | int counterStoreInstLongDouble = 0; 7 | 8 | int counterLoadInstFloat = 0; 9 | int counterLoadInstDouble = 0; 10 | int counterLoadInstLongDouble = 0; 11 | 12 | int counterArithOpInstFloat = 0; 13 | int counterArithOpInstDouble = 0; 14 | int counterArithOpInstLongDouble = 0; 15 | 16 | int counterCmpOpInstFloat = 0; 17 | int counterCmpOpInstDouble = 0; 18 | int counterCmpOpInstLongDouble = 0; 19 | 20 | int counterFPTruncInst = 0; 21 | int counterFPExtInst = 0; 22 | 23 | long int score = 0; 24 | 25 | // Store Instruction 26 | void incrementStoreInstFloat() { 27 | counterStoreInstFloat++; 28 | // score += 32; 29 | score += 8; 30 | } 31 | 32 | void incrementStoreInstDouble() { 33 | counterStoreInstDouble++; 34 | // score += 64; 35 | score += 8; 36 | } 37 | 38 | void incrementStoreInstLongDouble() { 39 | counterStoreInstLongDouble++; 40 | // score += 80; 41 | score += 8; 42 | } 43 | 44 | // Load Instruction 45 | void incrementLoadInstFloat() { 46 | counterLoadInstFloat++; 47 | // score += 32; 48 | score += 8; 49 | } 50 | 51 | void incrementLoadInstDouble() { 52 | counterLoadInstDouble++; 53 | // score += 64; 54 | score += 8; 55 | } 56 | 57 | void incrementLoadInstLongDouble() { 58 | counterLoadInstLongDouble++; 59 | // score += 80; 60 | score += 8; 61 | } 62 | 63 | // ArithOp Instruction 64 | void incrementArithOpInstFloat() { 65 | counterArithOpInstFloat++; 66 | // score += 32; 67 | score += 20; 68 | } 69 | 70 | void incrementArithOpInstDouble() { 71 | counterArithOpInstDouble++; 72 | // score += 64; 73 | score += 30; 74 | } 75 | 76 | void incrementArithOpInstLongDouble() { 77 | counterArithOpInstLongDouble++; 78 | // score += 80; 79 | score += 40; 80 | } 81 | 82 | 83 | // CmpOp Instruction 84 | void incrementCmpOpInstFloat() { 85 | counterCmpOpInstFloat++; 86 | // score += 32; 87 | score += 20; 88 | } 89 | 90 | void incrementCmpOpInstDouble() { 91 | counterCmpOpInstDouble++; 92 | // score += 64; 93 | score += 30; 94 | } 95 | 96 | void incrementCmpOpInstLongDouble() { 97 | counterCmpOpInstLongDouble++; 98 | // score += 80; 99 | score += 40; 100 | } 101 | 102 | 103 | // Cast Instructions 104 | void incrementFPTruncInst() { 105 | counterFPTruncInst++; 106 | // score += 32; 107 | score += 1; 108 | } 109 | 110 | void incrementFPExtInst() { 111 | counterFPExtInst++; 112 | // score += 32; 113 | score += 1; 114 | } 115 | 116 | 117 | 118 | // Printing counters 119 | void printCounters() { 120 | printf("StoreInst\n"); 121 | printf("\tFloat: %d\n", counterStoreInstFloat); 122 | printf("\tDouble: %d\n", counterStoreInstDouble); 123 | printf("\tLongDouble: %d\n", counterStoreInstLongDouble); 124 | 125 | printf("LoadInst\n"); 126 | printf("\tFloat: %d\n", counterLoadInstFloat); 127 | printf("\tDouble: %d\n", counterLoadInstDouble); 128 | printf("\tLongDouble: %d\n", counterLoadInstLongDouble); 129 | 130 | printf("ArithOpInst\n"); 131 | printf("\tFloat: %d\n", counterArithOpInstFloat); 132 | printf("\tDouble: %d\n", counterArithOpInstDouble); 133 | printf("\tLongDouble: %d\n", counterArithOpInstLongDouble); 134 | 135 | printf("CmpOpInst\n"); 136 | printf("\tFloat: %d\n", counterCmpOpInstFloat); 137 | printf("\tDouble: %d\n", counterCmpOpInstDouble); 138 | printf("\tLongDouble: %d\n", counterCmpOpInstLongDouble); 139 | 140 | printf("CastInst\n"); 141 | printf("\tTruncInst: %d\n", counterFPTruncInst); 142 | printf("\tExtInst: %d\n", counterFPExtInst); 143 | 144 | printf("Score: %ld\n", score); 145 | 146 | FILE* file; 147 | file = fopen("score.cov", "w"); 148 | fprintf(file, "%ld\n", score); 149 | 150 | return; 151 | } 152 | -------------------------------------------------------------------------------- /src/exclude_coverage.txt: -------------------------------------------------------------------------------- 1 | printBranch 2 | printBranchTo 3 | cov_log 4 | cov_check 5 | cov_arr_log 6 | cov_spec_log 7 | cov_arr_spec_log 8 | cov_rand 9 | cov_rand_sp 10 | current_time_ns 11 | -------------------------------------------------------------------------------- /src/exclude_instrument.txt: -------------------------------------------------------------------------------- 1 | incrementStoreInstFloat 2 | incrementStoreInstDouble 3 | incrementStoreInstLongDouble 4 | incrementLoadInstFloat 5 | incrementLoadInstDouble 6 | incrementLoadInstLongDouble 7 | incrementArithOpInstFloat 8 | incrementArithOpInstDouble 9 | incrementArithOpInstLongDouble 10 | incrementFPTruncInst 11 | incrementFPExtInst 12 | printCounters 13 | cov_deserialize 14 | cov_serialize 15 | cov_log 16 | cov_check 17 | cov_arr_log 18 | cov_spec_log 19 | cov_arr_spec_log 20 | cov_rand 21 | cov_rand_sp 22 | current_time_ns 23 | main 24 | -------------------------------------------------------------------------------- /src/lib/vjson/.hgignore: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /src/lib/vjson/.svn/dir-prop-base: -------------------------------------------------------------------------------- 1 | K 10 2 | svn:ignore 3 | V 5 4 | *.os 5 | 6 | END 7 | -------------------------------------------------------------------------------- /src/lib/vjson/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 5302 5 | https://repo.eecs.berkeley.edu/svn/users/ksen/projects/corvette/src/lib/vjson 6 | https://repo.eecs.berkeley.edu/svn/users/ksen/projects 7 | 8 | 9 | 10 | 2012-12-21T05:04:52.831734Z 11 | 4285 12 | rubio 13 | has-props 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 1c3fd406-9068-4342-8353-511fcdf43622 28 | 29 | json.cpp 30 | file 31 | 32 | 33 | 34 | 35 | 2013-07-06T21:25:13.701227Z 36 | 87ba41a1d330c6a66f1cf896ae0550cc 37 | 2012-12-21T00:21:25.931509Z 38 | 4280 39 | nacuong 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 8505 62 | 63 | block_allocator.cpp 64 | file 65 | 66 | 67 | 68 | 69 | 2013-07-06T21:25:13.701227Z 70 | bd1f3a697d89842cdf3faae9792ca67d 71 | 2012-12-21T00:18:51.485481Z 72 | 4279 73 | nacuong 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 1082 96 | 97 | json.h 98 | file 99 | 100 | 101 | 102 | 103 | 2013-07-06T21:25:13.701227Z 104 | 879165007dfcc6fbd9d1bdbba032dabe 105 | 2012-12-21T00:21:25.931509Z 106 | 4280 107 | nacuong 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 546 130 | 131 | .hgignore 132 | file 133 | 134 | 135 | 136 | 137 | 2013-07-06T21:25:13.701227Z 138 | b0da275520918e23dd615e2a747528f1 139 | 2012-12-21T00:18:51.485481Z 140 | 4279 141 | nacuong 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 5 164 | 165 | block_allocator.h 166 | file 167 | 168 | 169 | 170 | 171 | 2013-07-06T21:25:13.701227Z 172 | 8e5199e196e8de68396ca7a8ddc9164e 173 | 2012-12-21T00:18:51.485481Z 174 | 4279 175 | nacuong 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 592 198 | 199 | -------------------------------------------------------------------------------- /src/lib/vjson/.svn/text-base/.hgignore.svn-base: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /src/lib/vjson/.svn/text-base/block_allocator.cpp.svn-base: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "block_allocator.h" 5 | 6 | block_allocator::block_allocator(size_t blocksize): m_head(0), m_blocksize(blocksize) 7 | { 8 | } 9 | 10 | block_allocator::~block_allocator() 11 | { 12 | while (m_head) 13 | { 14 | block *temp = m_head->next; 15 | ::free(m_head); 16 | m_head = temp; 17 | } 18 | } 19 | 20 | void block_allocator::swap(block_allocator &rhs) 21 | { 22 | std::swap(m_blocksize, rhs.m_blocksize); 23 | std::swap(m_head, rhs.m_head); 24 | } 25 | 26 | void *block_allocator::malloc(size_t size) 27 | { 28 | if ((m_head && m_head->used + size > m_head->size) || !m_head) 29 | { 30 | // calc needed size for allocation 31 | size_t alloc_size = std::max(sizeof(block) + size, m_blocksize); 32 | 33 | // create new block 34 | char *buffer = (char *)::malloc(alloc_size); 35 | block *b = reinterpret_cast(buffer); 36 | b->size = alloc_size; 37 | b->used = sizeof(block); 38 | b->buffer = buffer; 39 | b->next = m_head; 40 | m_head = b; 41 | } 42 | 43 | void *ptr = m_head->buffer + m_head->used; 44 | m_head->used += size; 45 | return ptr; 46 | } 47 | 48 | void block_allocator::free() 49 | { 50 | block_allocator(0).swap(*this); 51 | } 52 | -------------------------------------------------------------------------------- /src/lib/vjson/.svn/text-base/block_allocator.h.svn-base: -------------------------------------------------------------------------------- 1 | #ifndef BLOCK_ALLOCATOR_H 2 | #define BLOCK_ALLOCATOR_H 3 | 4 | #include 5 | 6 | class block_allocator 7 | { 8 | private: 9 | struct block 10 | { 11 | size_t size; 12 | size_t used; 13 | char *buffer; 14 | block *next; 15 | }; 16 | 17 | block *m_head; 18 | size_t m_blocksize; 19 | 20 | block_allocator(const block_allocator &); 21 | block_allocator &operator=(block_allocator &); 22 | 23 | public: 24 | block_allocator(size_t blocksize); 25 | ~block_allocator(); 26 | 27 | // exchange contents with rhs 28 | void swap(block_allocator &rhs); 29 | 30 | // allocate memory 31 | void *malloc(size_t size); 32 | 33 | // free all allocated blocks 34 | void free(); 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/lib/vjson/.svn/text-base/json.h.svn-base: -------------------------------------------------------------------------------- 1 | #ifndef JSON_H 2 | #define JSON_H 3 | 4 | #include "block_allocator.h" 5 | 6 | enum json_type 7 | { 8 | JSON_NULL, 9 | JSON_OBJECT, 10 | JSON_ARRAY, 11 | JSON_STRING, 12 | JSON_INT, 13 | JSON_FLOAT, 14 | JSON_BOOL, 15 | }; 16 | 17 | struct json_value 18 | { 19 | json_value *parent; 20 | json_value *next_sibling; 21 | json_value *first_child; 22 | json_value *last_child; 23 | 24 | char *name; 25 | union 26 | { 27 | char *string_value; 28 | int int_value; 29 | float float_value; 30 | }; 31 | 32 | json_type type; 33 | }; 34 | 35 | json_value *json_parse(char *source, char **error_pos, int *error_line, block_allocator *allocator); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/lib/vjson/block_allocator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "block_allocator.h" 5 | 6 | block_allocator::block_allocator(size_t blocksize): m_head(0), m_blocksize(blocksize) 7 | { 8 | } 9 | 10 | block_allocator::~block_allocator() 11 | { 12 | while (m_head) 13 | { 14 | block *temp = m_head->next; 15 | ::free(m_head); 16 | m_head = temp; 17 | } 18 | } 19 | 20 | void block_allocator::swap(block_allocator &rhs) 21 | { 22 | std::swap(m_blocksize, rhs.m_blocksize); 23 | std::swap(m_head, rhs.m_head); 24 | } 25 | 26 | void *block_allocator::malloc(size_t size) 27 | { 28 | if ((m_head && m_head->used + size > m_head->size) || !m_head) 29 | { 30 | // calc needed size for allocation 31 | size_t alloc_size = std::max(sizeof(block) + size, m_blocksize); 32 | 33 | // create new block 34 | char *buffer = (char *)::malloc(alloc_size); 35 | block *b = reinterpret_cast(buffer); 36 | b->size = alloc_size; 37 | b->used = sizeof(block); 38 | b->buffer = buffer; 39 | b->next = m_head; 40 | m_head = b; 41 | } 42 | 43 | void *ptr = m_head->buffer + m_head->used; 44 | m_head->used += size; 45 | return ptr; 46 | } 47 | 48 | void block_allocator::free() 49 | { 50 | block_allocator(0).swap(*this); 51 | } 52 | -------------------------------------------------------------------------------- /src/lib/vjson/block_allocator.h: -------------------------------------------------------------------------------- 1 | #ifndef BLOCK_ALLOCATOR_H 2 | #define BLOCK_ALLOCATOR_H 3 | 4 | #include 5 | 6 | class block_allocator 7 | { 8 | private: 9 | struct block 10 | { 11 | size_t size; 12 | size_t used; 13 | char *buffer; 14 | block *next; 15 | }; 16 | 17 | block *m_head; 18 | size_t m_blocksize; 19 | 20 | block_allocator(const block_allocator &); 21 | block_allocator &operator=(block_allocator &); 22 | 23 | public: 24 | block_allocator(size_t blocksize); 25 | ~block_allocator(); 26 | 27 | // exchange contents with rhs 28 | void swap(block_allocator &rhs); 29 | 30 | // allocate memory 31 | void *malloc(size_t size); 32 | 33 | // free all allocated blocks 34 | void free(); 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/lib/vjson/json.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_H 2 | #define JSON_H 3 | 4 | #include "block_allocator.h" 5 | 6 | enum json_type 7 | { 8 | JSON_NULL, 9 | JSON_OBJECT, 10 | JSON_ARRAY, 11 | JSON_STRING, 12 | JSON_INT, 13 | JSON_FLOAT, 14 | JSON_BOOL, 15 | }; 16 | 17 | struct json_value 18 | { 19 | json_value *parent; 20 | json_value *next_sibling; 21 | json_value *first_child; 22 | json_value *last_child; 23 | 24 | char *name; 25 | union 26 | { 27 | char *string_value; 28 | int int_value; 29 | float float_value; 30 | }; 31 | 32 | json_type type; 33 | }; 34 | 35 | json_value *json_parse(char *source, char **error_pos, int *error_line, block_allocator *allocator); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/tests/README: -------------------------------------------------------------------------------- 1 | 2 | To add a new test: 3 | 4 | 1) Create a new directory test#. 5 | 2) Add source.c: the file to transform. 6 | 3) Add source.json: the configuration reflecting the changes to be made. 7 | 4) Add expected.c: the hand-written source.c reflecting the changes. 8 | Make sure expected.c calls cov_spec_log instead of cov_log and cov_check. 9 | 5) Set the propedit svn:ignore property for the new directory. -------------------------------------------------------------------------------- /src/tests/SConscript: -------------------------------------------------------------------------------- 1 | Import('env') 2 | 3 | env = env.Clone( 4 | tools=[ 5 | 'bitcode', 6 | 'bitcode2text', 7 | 'compare', 8 | 'tests', 9 | 'pass', 10 | 'pass-builder', 11 | 'run', 12 | ], 13 | toolpath=[ 14 | '#src/tests', 15 | ]) 16 | 17 | #Alias('test-llvm', '.') 18 | 19 | 20 | 21 | ######################################################################## 22 | # 23 | # full test suite starting from C source code 24 | # 25 | 26 | for testdir in env.Tests(): 27 | tenv = env.Clone() 28 | 29 | # find source file 30 | source = testdir.File('source.c') 31 | 32 | # translate source to bitcode 33 | suffix = tenv.Bitcode.builder.suffix 34 | bitcode = testdir.File('source' + suffix) 35 | tenv.Bitcode(bitcode, source) 36 | Alias('test-bitcode', bitcode) 37 | 38 | # find config file 39 | tenv['CONFIG_FILE'] = testdir.File('source.json') 40 | tenv['EXCLUDE_FILE'] = testdir.File('exclude.txt') 41 | tenv['INCLUDE_FILE'] = testdir.File('include.txt') 42 | 43 | # run pass on bitcode file 44 | tbitcode = testdir.File('transformed.bc') 45 | tenv.LlvmPass(tbitcode, bitcode) 46 | Alias('test-pass', tbitcode) 47 | Alias('test', tbitcode) 48 | 49 | # translate modified program to bitcode 50 | expected = testdir.File('expected.c') 51 | suffix = tenv.Bitcode.builder.suffix 52 | ebitcode = testdir.File('expected' + suffix) 53 | tenv.Bitcode(ebitcode, expected) 54 | Alias('test-ebitcode', ebitcode) 55 | 56 | # run expected program to create spec.cov 57 | spec = testdir.File('spec.cov') 58 | tenv.Run(spec, ebitcode) 59 | Alias('test', spec) 60 | 61 | # run transformed program to create log.cov 62 | log = testdir.File('log.cov') 63 | result = testdir.File('result.out') 64 | tenv.Run([log, result], [tbitcode, spec]) 65 | Alias('test', result) 66 | 67 | # did test pass? 68 | final_result = testdir.File('transformed.passed') 69 | tenv.Compare(final_result, result) 70 | Alias('test', final_result) 71 | 72 | -------------------------------------------------------------------------------- /src/tests/bitcode.py: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | 3 | 4 | ######################################################################## 5 | # 6 | # generate LLVM bitcode from C/C++ source using the Clang front end 7 | # 8 | 9 | 10 | __bitcode_action = 'clang -c -emit-llvm -o $TARGET $SOURCES' 11 | 12 | 13 | __bitcode_builder = Builder( 14 | action=__bitcode_action, 15 | src_suffix=['.c', '.cpp'], 16 | suffix='.bc', 17 | source_scanner=CScanner, 18 | ) 19 | 20 | 21 | ######################################################################## 22 | 23 | 24 | def generate(env): 25 | if 'Bitcode' in env['BUILDERS']: 26 | return 27 | 28 | env.AppendUnique( 29 | BUILDERS={'Bitcode': __bitcode_builder}, 30 | ) 31 | 32 | 33 | def exists(env): 34 | return env.WhereIs('clang') 35 | -------------------------------------------------------------------------------- /src/tests/bitcode2text.py: -------------------------------------------------------------------------------- 1 | from SCons.Action import Action 2 | from SCons.Builder import Builder 3 | 4 | 5 | ######################################################################## 6 | # 7 | # generate a sorted file 8 | # 9 | 10 | 11 | def __bitcode2text_emitter(target, source, env): 12 | #source.append(env['SortFile']) 13 | return target, source 14 | 15 | 16 | __bitcode2text_action = Action([[ 17 | '$Bitcode2Text.abspath', '$SOURCES', '>$TARGET' 18 | ]]) 19 | 20 | 21 | __bitcode2text_builder = Builder( 22 | emitter=__bitcode2text_emitter, 23 | action=__bitcode2text_action, 24 | ) 25 | 26 | 27 | 28 | 29 | ######################################################################## 30 | 31 | 32 | def generate(env): 33 | 34 | env.AppendUnique( 35 | Bitcode2Text=env.File('compare.sh'), 36 | BUILDERS={'Bitcode2Text': __bitcode2text_builder, 37 | }, 38 | ) 39 | 40 | 41 | def exists(env): 42 | return True 43 | -------------------------------------------------------------------------------- /src/tests/compare.py: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | 3 | import filecmp 4 | 5 | 6 | ######################################################################## 7 | # 8 | # comparison with reference output 9 | # 10 | 11 | 12 | def __compare_action_exec(target, source, env): 13 | __pychecker__ = 'no-argsused' 14 | [_source] = source 15 | linestring = open(str(_source), 'r').read() 16 | if 'true' in linestring: 17 | same = True 18 | else: 19 | same = False 20 | return ('file contents mismatch', False)[same] 21 | 22 | 23 | def __compare_action_show(target, source, env): 24 | __pychecker__ = 'no-argsused' 25 | [_source] = source 26 | return 'Checking result value in file "%s"' % str(_source) 27 | 28 | 29 | __compare_action = Action(__compare_action_exec, __compare_action_show) 30 | 31 | 32 | __compare_action = [__compare_action, Touch('$TARGET')] 33 | 34 | 35 | __compare_builder = Builder( 36 | action=__compare_action, 37 | suffix='.passed', 38 | ) 39 | 40 | 41 | ######################################################################## 42 | 43 | 44 | def generate(env): 45 | env.AppendUnique( 46 | BUILDERS={'Compare': __compare_builder}, 47 | ) 48 | 49 | 50 | def exists(env): 51 | return True 52 | -------------------------------------------------------------------------------- /src/tests/compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | opt -strip $1 -o tmp01.bc 4 | opt -strip $2 -o tmp02.bc 5 | llvm-dis < tmp01.bc > tmp01 6 | llvm-dis < tmp02.bc > tmp02 7 | diff=$(diff tmp01 tmp02 | wc -l) 8 | diff=$(echo $diff) 9 | if [[ "$diff" == "0" ]] 10 | then echo "true" 11 | else echo "false ($diff lines of differences)" 12 | fi 13 | -------------------------------------------------------------------------------- /src/tests/defaults.conf: -------------------------------------------------------------------------------- 1 | # Values given here serve as defaults if not overriden in a 2 | # per-test-case "test.conf" file. 3 | 4 | # details affecting analysis of WPDS after it has been generated 5 | [analyze wpds] 6 | 7 | # type of analysis to perform: dereference, info, input-output, 8 | # return, or standard 9 | analysis = standard 10 | 11 | # whether to run an additional analysis in "--handled" mode 12 | handled = false 13 | 14 | # details affecting generation of WPDS from program source code 15 | [create wpds] 16 | 17 | # whether this test case is enabled at all: all, cil, llvm, or none 18 | enabled = all 19 | 20 | # optional name of file listing function entry points, interpreted 21 | # relative to the directory containing the configuration file 22 | entry points = 23 | 24 | # whether to recognize error-handling patterns 25 | error handling = true 26 | 27 | # source language of test: C or C++ 28 | language = C 29 | 30 | # sign of error codes in this test: negative or positive 31 | sign = negative 32 | 33 | # whether to analyze transformations between integer- and 34 | # pointer-typed error codes 35 | transformation = false 36 | -------------------------------------------------------------------------------- /src/tests/extract.py: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | 3 | 4 | ######################################################################## 5 | # 6 | # extract bitcode file from executable 7 | # 8 | 9 | 10 | __extract_action = '/home/rubio/ksvnrepo/projects/corvette/scripts/llvm-wrapper/extract-bc $SOURCES' 11 | 12 | 13 | __extract_builder = Builder( 14 | action=__extract_action, 15 | suffix='.bc', 16 | source_scanner=CScanner, 17 | ) 18 | 19 | 20 | ######################################################################## 21 | 22 | 23 | def generate(env): 24 | if 'Extract' in env['BUILDERS']: 25 | return 26 | 27 | env.AppendUnique( 28 | BUILDERS={'Extract': __extract_builder}, 29 | ) 30 | 31 | 32 | def exists(env): 33 | return env.WhereIs('clang') 34 | -------------------------------------------------------------------------------- /src/tests/pass-builder.py: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | 3 | 4 | ######################################################################## 5 | # 6 | # generate a builder for weighted pushdown systems 7 | # 8 | 9 | 10 | def PASSBuilder(env, engine, action, suffix='.out', target_scanner=None, **kwargs): 11 | 12 | def pass_generator(target, source, env, for_signature): 13 | actions = [action] 14 | return actions 15 | 16 | def pass_target_scanner(node, env, path): 17 | deps = [env[engine]] 18 | if target_scanner: 19 | deps += target_scanner(node, env, path) 20 | return deps 21 | 22 | return Builder(generator=pass_generator, target_scanner=Scanner(pass_target_scanner), suffix=suffix, **kwargs) 23 | 24 | 25 | ######################################################################## 26 | 27 | 28 | def generate(env): 29 | if hasattr(env, 'PASSBuilder'): 30 | return 31 | 32 | env.AddMethod(PASSBuilder) 33 | 34 | 35 | def exists(env): 36 | return True 37 | -------------------------------------------------------------------------------- /src/tests/pass.py: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | 3 | 4 | ######################################################################## 5 | # 6 | # apply transformations to LLVM bitcode file 7 | # 8 | 9 | 10 | def plugin_ld_library_path(target, source, env, for_signature): 11 | compiler = env.WhereIs('$CXX') 12 | bindir = File(compiler).dir 13 | if bindir.path != '/usr/bin': 14 | libdir = Dir('lib', bindir.dir) 15 | envar = 'LD_LIBRARY_PATH=%s' % libdir 16 | return envar 17 | 18 | 19 | def generate(env): 20 | builder_name = 'LlvmPass' 21 | if builder_name in env['BUILDERS']: 22 | return 23 | 24 | env.Tool('pass-builder', toolpath=['#src/tests']) 25 | 26 | builder = env.PASSBuilder( 27 | engine='PASS_PLUGIN', 28 | action='$__VALGRIND $__PLUGIN_LD_LIBRARY_PATH opt -load $PASS_PLUGIN -variables -adjust-operators --die --time-passes -include=$INCLUDE_FILE -exclude=$EXCLUDE_FILE -json-config=$CONFIG_FILE -output=$TARGET $SOURCES > $TARGET', 29 | src_suffix=['.bc', '.ll'], 30 | src_builder='Extract', 31 | ) 32 | 33 | env.AppendUnique( 34 | BUILDERS={builder_name: builder}, 35 | PASS_PLUGIN=env.File('#src/Passes$SHLIBSUFFIX'), 36 | __PLUGIN_LD_LIBRARY_PATH=plugin_ld_library_path, 37 | ) 38 | 39 | 40 | def exists(env): 41 | return True 42 | -------------------------------------------------------------------------------- /src/tests/run.py: -------------------------------------------------------------------------------- 1 | from SCons.Script import * 2 | 3 | 4 | ######################################################################## 5 | # 6 | # running a bitcode file 7 | # 8 | 9 | 10 | __run_action = 'lli $SOURCES $TARGETS' 11 | 12 | 13 | __run_builder = Builder( 14 | action=__run_action, 15 | src_suffix=['.bc'], 16 | source_scanner=CScanner, 17 | ) 18 | 19 | 20 | ######################################################################## 21 | 22 | 23 | def generate(env): 24 | if 'Run' in env['BUILDERS']: 25 | return 26 | 27 | env.AppendUnique( 28 | BUILDERS={'Run': __run_builder}, 29 | ) 30 | 31 | 32 | def exists(env): 33 | return env.WhereIs('lli') 34 | -------------------------------------------------------------------------------- /src/tests/test1/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test1/expected.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | void cov_serialize(long double, unsigned char*, int); 7 | long double cov_deserialize(char*, int); 8 | void cov_log(long double, char*, char*); 9 | void cov_spec_log(long double, long double, char*); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_spec_arr_log(long double[], int, long double, char*); 12 | void cov_check(char*, char*); 13 | void cov_arr_check(char*, char*, int length); 14 | 15 | int main(int argc, char *argv[]) { 16 | float a = 2; 17 | double b = 3; 18 | double c = a + b; 19 | 20 | cov_spec_log(c, 0, argv[1]); // spec.cov 21 | 22 | return 0; 23 | } 24 | 25 | void cov_serialize(long double f, unsigned char* buf, int length) { 26 | int i; 27 | union { 28 | unsigned char bytes[10]; 29 | long double val; 30 | } bfconvert; 31 | 32 | bfconvert.val = f; 33 | 34 | for (i = 0; i < length; i++) { 35 | buf[i] = bfconvert.bytes[i]; 36 | } 37 | } 38 | 39 | long double cov_deserialize(char* buf, int length) { 40 | int i; 41 | unsigned int u; 42 | union { 43 | unsigned char bytes[10]; 44 | long double val; 45 | } bfconvert; 46 | 47 | for (i = 0; i < length; i++) { 48 | sscanf(buf, "%02X", &u); 49 | bfconvert.bytes[i] = u; 50 | buf += 2; 51 | } 52 | 53 | return bfconvert.val; 54 | } 55 | 56 | 57 | void cov_log(long double ld, char* msg, char* fn) { 58 | int ld_size, i; 59 | unsigned char* buf; 60 | FILE* file; 61 | 62 | file = fopen(fn, "a"); 63 | ld_size = 10; 64 | buf = malloc(ld_size); 65 | 66 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 67 | cov_serialize(ld, buf, ld_size); 68 | for (i = 0; i < ld_size; i++) { 69 | fprintf(file, "%02X", buf[i]); 70 | } 71 | fprintf(file, "\n"); 72 | fclose(file); 73 | } 74 | 75 | void cov_spec_log(long double ideal, long double delta, char* fn) { 76 | cov_log(ideal, "ideal", fn); 77 | cov_log(delta, "delta", fn); 78 | } 79 | 80 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) { 81 | int ld_size, i, j; 82 | unsigned char* buf; 83 | FILE *file; 84 | 85 | file = fopen(fn, "a"); 86 | ld_size = 10; 87 | buf = malloc(ld_size); 88 | 89 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 90 | for (i = 0; i < size; i++) { 91 | long double ld = lds[i]; 92 | cov_serialize(ld, buf, ld_size); 93 | if (i > 0) fprintf(file, " "); 94 | for (j = 0; j < ld_size; j++) { 95 | fprintf(file, "%02X", buf[j]); 96 | } 97 | } 98 | fprintf(file, "\n"); 99 | fclose(file); 100 | } 101 | 102 | void cov_spec_arr_log(long double ideal[], int size, long double delta, char* fn) { 103 | cov_arr_log(ideal, size, "ideal", fn); 104 | cov_log(delta, "delta", fn); 105 | } 106 | 107 | 108 | void cov_check(char* log, char* spec) { 109 | char line[80], estimate_hex[80], ideal_hex[80], delta_hex[80]; 110 | long double estimate, ideal, delta, diff; 111 | FILE *log_file, *spec_file; 112 | int ld_size; 113 | 114 | ld_size = 10; 115 | 116 | // reading log file 117 | log_file = fopen(log, "rt"); 118 | while (fgets(line, 80, log_file) != NULL) { 119 | if (line[0] != '#') strcpy(estimate_hex, line); 120 | } 121 | fclose(log_file); 122 | 123 | spec_file = fopen(spec, "rt"); 124 | while (fgets(line, 80, spec_file) != NULL) { 125 | if (strncmp(line, "#ideal", 6) == 0) { 126 | fgets(ideal_hex, 80, spec_file); 127 | } else if (strncmp(line, "#delta", 6) == 0) { 128 | fgets(delta_hex, 80, spec_file); 129 | } 130 | } 131 | fclose(spec_file); 132 | 133 | // compare log and spec results 134 | estimate = cov_deserialize(estimate_hex, ld_size); 135 | ideal = cov_deserialize(ideal_hex, ld_size); 136 | delta = cov_deserialize(delta_hex, ld_size); 137 | 138 | if (estimate > ideal) diff = estimate - ideal; 139 | else diff = ideal - estimate; 140 | 141 | if (delta >= diff) printf("true\n"); 142 | else printf("false\n"); 143 | } 144 | 145 | void cov_arr_check(char* log, char* spec, int length) { 146 | char line[1000]; 147 | char *word, *sep, *brkt, *brkb; 148 | long double estimate[length], ideal[length], delta; 149 | FILE *log_file, *spec_file; 150 | int ld_size, cnt, i, predicate; 151 | 152 | sep = " "; 153 | ld_size = 10; 154 | 155 | // reading log file 156 | log_file = fopen(log, "rt"); 157 | while (fgets(line, 1000, log_file) != NULL) { 158 | if (line[0] != '#') { 159 | cnt = 0; 160 | for (word = strtok_r(line, sep, &brkt); 161 | word; 162 | word = strtok_r(NULL, sep, &brkt)){ 163 | estimate[cnt] = cov_deserialize(word, ld_size); 164 | cnt++; 165 | } 166 | } 167 | } 168 | fclose(log_file); 169 | 170 | // reading spec file 171 | spec_file = fopen(spec, "rt"); 172 | while (fgets(line, 1000, log_file) != NULL) { 173 | if (strncmp(line, "#ideal", 6) == 0) { 174 | cnt = 0; 175 | fgets(line, 1000, spec_file); 176 | for (word = strtok_r(line, sep, &brkb); 177 | word; 178 | word = strtok_r(NULL, sep, &brkb)){ 179 | ideal[cnt] = cov_deserialize(word, ld_size); 180 | cnt++; 181 | } 182 | } else if (strncmp(line, "#delta", 6) == 0) { 183 | fgets(line, 80, spec_file); 184 | delta = cov_deserialize(line, ld_size); 185 | } 186 | } 187 | fclose(spec_file); 188 | 189 | predicate = 1; 190 | for (i = 0; i < length; i++) { 191 | long double diff; 192 | if (estimate[i] > ideal[i]) diff = estimate[i] - ideal[i]; 193 | else diff = ideal[i] - estimate[i]; 194 | if (delta < diff) { 195 | predicate = 0; 196 | break; 197 | } 198 | } 199 | 200 | if (predicate) printf("true\n"); 201 | else printf("false\n"); 202 | } 203 | -------------------------------------------------------------------------------- /src/tests/test1/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test1/source.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | void cov_serialize(long double, unsigned char*, int); 7 | long double cov_deserialize(char*, int); 8 | void cov_log(long double, char*, char*); 9 | void cov_spec_log(long double, long double, char*); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_spec_arr_log(long double[], int, long double, char*); 12 | void cov_check(char*, char*, char*); 13 | void cov_arr_check(char*, char*, int length); 14 | 15 | int main(int argc, char *argv[]) { 16 | double a = 2; 17 | double b = 3; 18 | double c = a + b; 19 | 20 | cov_log(c, "result", argv[2]); // log.cov 21 | cov_check(argv[2], argv[1], argv[3]); // log.cov, spec.cov, result.out 22 | 23 | return 0; 24 | } 25 | 26 | void cov_serialize(long double f, unsigned char* buf, int length) { 27 | int i; 28 | union { 29 | unsigned char bytes[10]; 30 | long double val; 31 | } bfconvert; 32 | 33 | bfconvert.val = f; 34 | 35 | for (i = 0; i < length; i++) { 36 | buf[i] = bfconvert.bytes[i]; 37 | } 38 | } 39 | 40 | long double cov_deserialize(char* buf, int length) { 41 | int i; 42 | unsigned int u; 43 | union { 44 | unsigned char bytes[10]; 45 | long double val; 46 | } bfconvert; 47 | 48 | for (i = 0; i < length; i++) { 49 | sscanf(buf, "%02X", &u); 50 | bfconvert.bytes[i] = u; 51 | buf += 2; 52 | } 53 | 54 | return bfconvert.val; 55 | } 56 | 57 | 58 | void cov_log(long double ld, char* msg, char* fn) { 59 | int ld_size, i; 60 | unsigned char* buf; 61 | FILE* file; 62 | 63 | file = fopen(fn, "a"); 64 | ld_size = 10; 65 | buf = malloc(ld_size); 66 | 67 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 68 | cov_serialize(ld, buf, ld_size); 69 | for (i = 0; i < ld_size; i++) { 70 | fprintf(file, "%02X", buf[i]); 71 | } 72 | fprintf(file, "\n"); 73 | fclose(file); 74 | } 75 | 76 | void cov_spec_log(long double ideal, long double delta, char* fn) { 77 | cov_log(ideal, "ideal", fn); 78 | cov_log(delta, "delta", fn); 79 | } 80 | 81 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) { 82 | int ld_size, i, j; 83 | unsigned char* buf; 84 | FILE *file; 85 | 86 | file = fopen(fn, "a"); 87 | ld_size = 10; 88 | buf = malloc(ld_size); 89 | 90 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 91 | for (i = 0; i < size; i++) { 92 | long double ld = lds[i]; 93 | cov_serialize(ld, buf, ld_size); 94 | if (i > 0) fprintf(file, " "); 95 | for (j = 0; j < ld_size; j++) { 96 | fprintf(file, "%02X", buf[j]); 97 | } 98 | } 99 | fprintf(file, "\n"); 100 | fclose(file); 101 | } 102 | 103 | void cov_spec_arr_log(long double ideal[], int size, long double delta, char* fn) { 104 | cov_arr_log(ideal, size, "ideal", fn); 105 | cov_log(delta, "delta", fn); 106 | } 107 | 108 | 109 | void cov_check(char* log, char* spec, char* result) { 110 | char line[80], estimate_hex[80], ideal_hex[80], delta_hex[80]; 111 | long double estimate, ideal, delta, diff; 112 | FILE *log_file, *spec_file, *result_file; 113 | int ld_size; 114 | 115 | ld_size = 10; 116 | 117 | // reading log file 118 | log_file = fopen(log, "rt"); 119 | while (fgets(line, 80, log_file) != NULL) { 120 | if (line[0] != '#') strcpy(estimate_hex, line); 121 | } 122 | fclose(log_file); 123 | 124 | spec_file = fopen(spec, "rt"); 125 | while (fgets(line, 80, spec_file) != NULL) { 126 | if (strncmp(line, "#ideal", 6) == 0) { 127 | fgets(ideal_hex, 80, spec_file); 128 | } else if (strncmp(line, "#delta", 6) == 0) { 129 | fgets(delta_hex, 80, spec_file); 130 | } 131 | } 132 | fclose(spec_file); 133 | 134 | // compare log and spec results 135 | estimate = cov_deserialize(estimate_hex, ld_size); 136 | ideal = cov_deserialize(ideal_hex, ld_size); 137 | delta = cov_deserialize(delta_hex, ld_size); 138 | 139 | if (estimate > ideal) diff = estimate - ideal; 140 | else diff = ideal - estimate; 141 | 142 | result_file = fopen(result, "w"); 143 | if (delta >= diff) fprintf(result_file, "true\n"); 144 | else fprintf(result_file, "false\n"); 145 | fclose(result_file); 146 | } 147 | 148 | void cov_arr_check(char* log, char* spec, int length) { 149 | char line[1000]; 150 | char *word, *sep, *brkt, *brkb; 151 | long double estimate[length], ideal[length], delta; 152 | FILE *log_file, *spec_file; 153 | int ld_size, cnt, i, predicate; 154 | 155 | sep = " "; 156 | ld_size = 10; 157 | 158 | // reading log file 159 | log_file = fopen(log, "rt"); 160 | while (fgets(line, 1000, log_file) != NULL) { 161 | if (line[0] != '#') { 162 | cnt = 0; 163 | for (word = strtok_r(line, sep, &brkt); 164 | word; 165 | word = strtok_r(NULL, sep, &brkt)){ 166 | estimate[cnt] = cov_deserialize(word, ld_size); 167 | cnt++; 168 | } 169 | } 170 | } 171 | fclose(log_file); 172 | 173 | // reading spec file 174 | spec_file = fopen(spec, "rt"); 175 | while (fgets(line, 1000, log_file) != NULL) { 176 | if (strncmp(line, "#ideal", 6) == 0) { 177 | cnt = 0; 178 | fgets(line, 1000, spec_file); 179 | for (word = strtok_r(line, sep, &brkb); 180 | word; 181 | word = strtok_r(NULL, sep, &brkb)){ 182 | ideal[cnt] = cov_deserialize(word, ld_size); 183 | cnt++; 184 | } 185 | } else if (strncmp(line, "#delta", 6) == 0) { 186 | fgets(line, 80, spec_file); 187 | delta = cov_deserialize(line, ld_size); 188 | } 189 | } 190 | fclose(spec_file); 191 | 192 | predicate = 1; 193 | for (i = 0; i < length; i++) { 194 | long double diff; 195 | if (estimate[i] > ideal[i]) diff = estimate[i] - ideal[i]; 196 | else diff = ideal[i] - estimate[i]; 197 | if (delta < diff) { 198 | predicate = 0; 199 | break; 200 | } 201 | } 202 | 203 | if (predicate) printf("true\n"); 204 | else printf("false\n"); 205 | } 206 | -------------------------------------------------------------------------------- /src/tests/test1/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer", 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "a", 10 | "type": "float", 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "b", 15 | "type": "double", 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "c", 20 | "type": "double", 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "argc", 25 | "type": "int", 26 | }, 27 | "op": { 28 | "id": "18", 29 | "function": "main", 30 | "name": "fadd", 31 | "type": "double", 32 | }, 33 | } 34 | -------------------------------------------------------------------------------- /src/tests/test10/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test10/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | calculate 3 | -------------------------------------------------------------------------------- /src/tests/test10/include_global.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corvette-berkeley/precimonious/5ac56e145379bc059d686af10c62c3750224edd3/src/tests/test10/include_global.txt -------------------------------------------------------------------------------- /src/tests/test10/searchFile.json: -------------------------------------------------------------------------------- 1 | {"config": [ 2 | {"localVar": { 3 | "function": "main", 4 | "name": "c", 5 | "type": ["float[4]", "double[4]", "longdouble[4]"] 6 | }}, 7 | {"localVar": { 8 | "function": "main", 9 | "name": "result", 10 | "type": ["float", "double", "longdouble"] 11 | }}, 12 | {"localVar": { 13 | "function": "calculate", 14 | "name": "x", 15 | "type": ["float*", "double*", "longdouble*"] 16 | }}, 17 | {"localVar": { 18 | "function": "calculate", 19 | "name": "count", 20 | "type": ["float", "double", "longdouble"] 21 | }} 22 | ]} 23 | -------------------------------------------------------------------------------- /src/tests/test10/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "c", 5 | "type": "double[4]" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "result", 10 | "type": "longdouble" 11 | }, 12 | "localVar": { 13 | "function": "calculate", 14 | "name": "x", 15 | "type": "double*" 16 | }, 17 | "localVar": { 18 | "function": "calculate", 19 | "name": "count", 20 | "type": "longdouble" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tests/test11/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test11/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test11/include_global.txt: -------------------------------------------------------------------------------- 1 | a 2 | -------------------------------------------------------------------------------- /src/tests/test11/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "globalVar": { 3 | "name": "a", 4 | "type": "float*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/tests/test2/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test2/expected.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | void cov_serialize(long double, unsigned char*, int); 7 | long double cov_deserialize(char*, int); 8 | void cov_log(long double, char*, char*); 9 | void cov_spec_log(long double, long double, char*); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_spec_arr_log(long double[], int, long double, char*); 12 | void cov_check(char*, char*, char*); 13 | void cov_arr_check(char*, char*, int length); 14 | 15 | double foo(float x, double y) { 16 | return x + y + 3; 17 | } 18 | 19 | 20 | int main(int argc, char *argv[]) { 21 | double a = 2; 22 | double b = 3; 23 | double c = foo(a + b, a); 24 | 25 | cov_spec_log(c, 0, argv[1]); 26 | 27 | return 0; 28 | } 29 | 30 | void cov_serialize(long double f, unsigned char* buf, int length) { 31 | int i; 32 | union { 33 | unsigned char bytes[10]; 34 | long double val; 35 | } bfconvert; 36 | 37 | bfconvert.val = f; 38 | 39 | for (i = 0; i < length; i++) { 40 | buf[i] = bfconvert.bytes[i]; 41 | } 42 | } 43 | 44 | long double cov_deserialize(char* buf, int length) { 45 | int i; 46 | unsigned int u; 47 | union { 48 | unsigned char bytes[10]; 49 | long double val; 50 | } bfconvert; 51 | 52 | for (i = 0; i < length; i++) { 53 | sscanf(buf, "%02X", &u); 54 | bfconvert.bytes[i] = u; 55 | buf += 2; 56 | } 57 | 58 | return bfconvert.val; 59 | } 60 | 61 | 62 | void cov_log(long double ld, char* msg, char* fn) { 63 | int ld_size, i; 64 | unsigned char* buf; 65 | FILE* file; 66 | 67 | file = fopen(fn, "a"); 68 | ld_size = 10; 69 | buf = malloc(ld_size); 70 | 71 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 72 | cov_serialize(ld, buf, ld_size); 73 | for (i = 0; i < ld_size; i++) { 74 | fprintf(file, "%02X", buf[i]); 75 | } 76 | fprintf(file, "\n"); 77 | fclose(file); 78 | } 79 | 80 | void cov_spec_log(long double ideal, long double delta, char* fn) { 81 | cov_log(ideal, "ideal", fn); 82 | cov_log(delta, "delta", fn); 83 | } 84 | 85 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) { 86 | int ld_size, i, j; 87 | unsigned char* buf; 88 | FILE *file; 89 | 90 | file = fopen(fn, "a"); 91 | ld_size = 10; 92 | buf = malloc(ld_size); 93 | 94 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 95 | for (i = 0; i < size; i++) { 96 | long double ld = lds[i]; 97 | cov_serialize(ld, buf, ld_size); 98 | if (i > 0) fprintf(file, " "); 99 | for (j = 0; j < ld_size; j++) { 100 | fprintf(file, "%02X", buf[j]); 101 | } 102 | } 103 | fprintf(file, "\n"); 104 | fclose(file); 105 | } 106 | 107 | void cov_spec_arr_log(long double ideal[], int size, long double delta, char* fn) { 108 | cov_arr_log(ideal, size, "ideal", fn); 109 | cov_log(delta, "delta", fn); 110 | } 111 | 112 | 113 | void cov_check(char* log, char* spec, char* result) { 114 | char line[80], estimate_hex[80], ideal_hex[80], delta_hex[80]; 115 | long double estimate, ideal, delta, diff; 116 | FILE *log_file, *spec_file, *result_file; 117 | int ld_size; 118 | 119 | ld_size = 10; 120 | 121 | // reading log file 122 | log_file = fopen(log, "rt"); 123 | while (fgets(line, 80, log_file) != NULL) { 124 | if (line[0] != '#') strcpy(estimate_hex, line); 125 | } 126 | fclose(log_file); 127 | 128 | spec_file = fopen(spec, "rt"); 129 | while (fgets(line, 80, spec_file) != NULL) { 130 | if (strncmp(line, "#ideal", 6) == 0) { 131 | fgets(ideal_hex, 80, spec_file); 132 | } else if (strncmp(line, "#delta", 6) == 0) { 133 | fgets(delta_hex, 80, spec_file); 134 | } 135 | } 136 | fclose(spec_file); 137 | 138 | // compare log and spec results 139 | estimate = cov_deserialize(estimate_hex, ld_size); 140 | ideal = cov_deserialize(ideal_hex, ld_size); 141 | delta = cov_deserialize(delta_hex, ld_size); 142 | 143 | if (estimate > ideal) diff = estimate - ideal; 144 | else diff = ideal - estimate; 145 | 146 | result_file = fopen(result, "w"); 147 | if (delta >= diff) fprintf(result_file, "true\n"); 148 | else fprintf(result_file, "false\n"); 149 | fclose(result_file); 150 | } 151 | 152 | void cov_arr_check(char* log, char* spec, int length) { 153 | char line[1000]; 154 | char *word, *sep, *brkt, *brkb; 155 | long double estimate[length], ideal[length], delta; 156 | FILE *log_file, *spec_file; 157 | int ld_size, cnt, i, predicate; 158 | 159 | sep = " "; 160 | ld_size = 10; 161 | 162 | // reading log file 163 | log_file = fopen(log, "rt"); 164 | while (fgets(line, 1000, log_file) != NULL) { 165 | if (line[0] != '#') { 166 | cnt = 0; 167 | for (word = strtok_r(line, sep, &brkt); 168 | word; 169 | word = strtok_r(NULL, sep, &brkt)){ 170 | estimate[cnt] = cov_deserialize(word, ld_size); 171 | cnt++; 172 | } 173 | } 174 | } 175 | fclose(log_file); 176 | 177 | // reading spec file 178 | spec_file = fopen(spec, "rt"); 179 | while (fgets(line, 1000, log_file) != NULL) { 180 | if (strncmp(line, "#ideal", 6) == 0) { 181 | cnt = 0; 182 | fgets(line, 1000, spec_file); 183 | for (word = strtok_r(line, sep, &brkb); 184 | word; 185 | word = strtok_r(NULL, sep, &brkb)){ 186 | ideal[cnt] = cov_deserialize(word, ld_size); 187 | cnt++; 188 | } 189 | } else if (strncmp(line, "#delta", 6) == 0) { 190 | fgets(line, 80, spec_file); 191 | delta = cov_deserialize(line, ld_size); 192 | } 193 | } 194 | fclose(spec_file); 195 | 196 | predicate = 1; 197 | for (i = 0; i < length; i++) { 198 | long double diff; 199 | if (estimate[i] > ideal[i]) diff = estimate[i] - ideal[i]; 200 | else diff = ideal[i] - estimate[i]; 201 | if (delta < diff) { 202 | predicate = 0; 203 | break; 204 | } 205 | } 206 | 207 | if (predicate) printf("true\n"); 208 | else printf("false\n"); 209 | } 210 | -------------------------------------------------------------------------------- /src/tests/test2/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | foo 3 | -------------------------------------------------------------------------------- /src/tests/test2/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "foo", 4 | "name": "x", 5 | "type": "float" 6 | }, 7 | "op": { 8 | "id": "3", 9 | "function": "foo", 10 | "name": "fadd", 11 | "type": "double" 12 | }, 13 | "localVar": { 14 | "function": "main", 15 | "name": "argv", 16 | "type": "pointer" 17 | }, 18 | "localVar": { 19 | "function": "main", 20 | "name": "a", 21 | "type": "double" 22 | }, 23 | "localVar": { 24 | "function": "main", 25 | "name": "b", 26 | "type": "double" 27 | }, 28 | "localVar": { 29 | "function": "main", 30 | "name": "c", 31 | "type": "double" 32 | }, 33 | "localVar": { 34 | "function": "main", 35 | "name": "argc", 36 | "type": "int" 37 | }, 38 | "op": { 39 | "id": "18", 40 | "function": "main", 41 | "name": "fadd", 42 | "type": "double" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/tests/test3/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test3/expected.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | void cov_serialize(long double, unsigned char*, int); 7 | long double cov_deserialize(char*, int); 8 | void cov_log(long double, char*, char*); 9 | void cov_spec_log(long double, long double, char*); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_spec_arr_log(long double[], int, long double, char*); 12 | void cov_check(char*, char*, char*); 13 | void cov_arr_check(char*, char*, int length); 14 | 15 | 16 | int main(int argc, char *argv[]) { 17 | float a[3] = {2.1, 2.2, 2.3}; 18 | double b = 3; 19 | double c = a[1] + b; 20 | 21 | cov_spec_log(c, 0, argv[1]); 22 | printf("%1.15e\n", c); 23 | 24 | return 0; 25 | } 26 | 27 | 28 | void cov_serialize(long double f, unsigned char* buf, int length) { 29 | int i; 30 | union { 31 | unsigned char bytes[10]; 32 | long double val; 33 | } bfconvert; 34 | 35 | bfconvert.val = f; 36 | 37 | for (i = 0; i < length; i++) { 38 | buf[i] = bfconvert.bytes[i]; 39 | } 40 | } 41 | 42 | long double cov_deserialize(char* buf, int length) { 43 | int i; 44 | unsigned int u; 45 | union { 46 | unsigned char bytes[10]; 47 | long double val; 48 | } bfconvert; 49 | 50 | for (i = 0; i < length; i++) { 51 | sscanf(buf, "%02X", &u); 52 | bfconvert.bytes[i] = u; 53 | buf += 2; 54 | } 55 | 56 | return bfconvert.val; 57 | } 58 | 59 | 60 | void cov_log(long double ld, char* msg, char* fn) { 61 | int ld_size, i; 62 | unsigned char* buf; 63 | FILE* file; 64 | 65 | file = fopen(fn, "a"); 66 | ld_size = 10; 67 | buf = malloc(ld_size); 68 | 69 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 70 | cov_serialize(ld, buf, ld_size); 71 | for (i = 0; i < ld_size; i++) { 72 | fprintf(file, "%02X", buf[i]); 73 | } 74 | fprintf(file, "\n"); 75 | fclose(file); 76 | } 77 | 78 | void cov_spec_log(long double ideal, long double delta, char* fn) { 79 | cov_log(ideal, "ideal", fn); 80 | cov_log(delta, "delta", fn); 81 | } 82 | 83 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) { 84 | int ld_size, i, j; 85 | unsigned char* buf; 86 | FILE *file; 87 | 88 | file = fopen(fn, "a"); 89 | ld_size = 10; 90 | buf = malloc(ld_size); 91 | 92 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 93 | for (i = 0; i < size; i++) { 94 | long double ld = lds[i]; 95 | cov_serialize(ld, buf, ld_size); 96 | if (i > 0) fprintf(file, " "); 97 | for (j = 0; j < ld_size; j++) { 98 | fprintf(file, "%02X", buf[j]); 99 | } 100 | } 101 | fprintf(file, "\n"); 102 | fclose(file); 103 | } 104 | 105 | void cov_spec_arr_log(long double ideal[], int size, long double delta, char* fn) { 106 | cov_arr_log(ideal, size, "ideal", fn); 107 | cov_log(delta, "delta", fn); 108 | } 109 | 110 | 111 | void cov_check(char* log, char* spec, char* result) { 112 | char line[80], estimate_hex[80], ideal_hex[80], delta_hex[80]; 113 | long double estimate, ideal, delta, diff; 114 | FILE *log_file, *spec_file, *result_file; 115 | int ld_size; 116 | 117 | ld_size = 10; 118 | 119 | // reading log file 120 | log_file = fopen(log, "rt"); 121 | while (fgets(line, 80, log_file) != NULL) { 122 | if (line[0] != '#') strcpy(estimate_hex, line); 123 | } 124 | fclose(log_file); 125 | 126 | spec_file = fopen(spec, "rt"); 127 | while (fgets(line, 80, spec_file) != NULL) { 128 | if (strncmp(line, "#ideal", 6) == 0) { 129 | fgets(ideal_hex, 80, spec_file); 130 | } else if (strncmp(line, "#delta", 6) == 0) { 131 | fgets(delta_hex, 80, spec_file); 132 | } 133 | } 134 | fclose(spec_file); 135 | 136 | // compare log and spec results 137 | estimate = cov_deserialize(estimate_hex, ld_size); 138 | ideal = cov_deserialize(ideal_hex, ld_size); 139 | delta = cov_deserialize(delta_hex, ld_size); 140 | 141 | if (estimate > ideal) diff = estimate - ideal; 142 | else diff = ideal - estimate; 143 | 144 | result_file = fopen(result, "w"); 145 | if (delta >= diff) fprintf(result_file, "true\n"); 146 | else fprintf(result_file, "false\n"); 147 | fclose(result_file); 148 | } 149 | 150 | void cov_arr_check(char* log, char* spec, int length) { 151 | char line[1000]; 152 | char *word, *sep, *brkt, *brkb; 153 | long double estimate[length], ideal[length], delta; 154 | FILE *log_file, *spec_file; 155 | int ld_size, cnt, i, predicate; 156 | 157 | sep = " "; 158 | ld_size = 10; 159 | 160 | // reading log file 161 | log_file = fopen(log, "rt"); 162 | while (fgets(line, 1000, log_file) != NULL) { 163 | if (line[0] != '#') { 164 | cnt = 0; 165 | for (word = strtok_r(line, sep, &brkt); 166 | word; 167 | word = strtok_r(NULL, sep, &brkt)){ 168 | estimate[cnt] = cov_deserialize(word, ld_size); 169 | cnt++; 170 | } 171 | } 172 | } 173 | fclose(log_file); 174 | 175 | // reading spec file 176 | spec_file = fopen(spec, "rt"); 177 | while (fgets(line, 1000, log_file) != NULL) { 178 | if (strncmp(line, "#ideal", 6) == 0) { 179 | cnt = 0; 180 | fgets(line, 1000, spec_file); 181 | for (word = strtok_r(line, sep, &brkb); 182 | word; 183 | word = strtok_r(NULL, sep, &brkb)){ 184 | ideal[cnt] = cov_deserialize(word, ld_size); 185 | cnt++; 186 | } 187 | } else if (strncmp(line, "#delta", 6) == 0) { 188 | fgets(line, 80, spec_file); 189 | delta = cov_deserialize(line, ld_size); 190 | } 191 | } 192 | fclose(spec_file); 193 | 194 | predicate = 1; 195 | for (i = 0; i < length; i++) { 196 | long double diff; 197 | if (estimate[i] > ideal[i]) diff = estimate[i] - ideal[i]; 198 | else diff = ideal[i] - estimate[i]; 199 | if (delta < diff) { 200 | predicate = 0; 201 | break; 202 | } 203 | } 204 | 205 | if (predicate) printf("true\n"); 206 | else printf("false\n"); 207 | } 208 | -------------------------------------------------------------------------------- /src/tests/test3/functions.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test3/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test3/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "a", 5 | "type": "float[3]" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "b", 10 | "type": "double" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "c", 15 | "type": "double" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "retval", 20 | "type": "int" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "argv", 25 | "type": "pointer" 26 | }, 27 | "localVar": { 28 | "function": "main", 29 | "name": "argc", 30 | "type": "int" 31 | }, 32 | "op": { 33 | "id": "20", 34 | "function": "main", 35 | "name": "fadd", 36 | "type": "double" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/tests/test4/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test4/expected.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | void cov_serialize(long double, unsigned char*, int); 7 | long double cov_deserialize(char*, int); 8 | void cov_log(long double, char*, char*); 9 | void cov_spec_log(long double, long double, char*); 10 | void cov_arr_log(long double[], int, char*, char*); 11 | void cov_spec_arr_log(long double[], int, long double, char*); 12 | void cov_check(char*, char*, char*); 13 | void cov_arr_check(char*, char*, int length); 14 | 15 | 16 | int main(int argc, char *argv[]) { 17 | float a = 2.2L; 18 | float b = 2.2L; 19 | long double c = a + b; 20 | 21 | cov_spec_log(c, 0, argv[1]); 22 | printf("%1.15Le\n", c); 23 | printf("%1.15Le\n", (long double)a); 24 | 25 | return 0; 26 | } 27 | 28 | 29 | void cov_serialize(long double f, unsigned char* buf, int length) { 30 | int i; 31 | union { 32 | unsigned char bytes[10]; 33 | long double val; 34 | } bfconvert; 35 | 36 | bfconvert.val = f; 37 | 38 | for (i = 0; i < length; i++) { 39 | buf[i] = bfconvert.bytes[i]; 40 | } 41 | } 42 | 43 | long double cov_deserialize(char* buf, int length) { 44 | int i; 45 | unsigned int u; 46 | union { 47 | unsigned char bytes[10]; 48 | long double val; 49 | } bfconvert; 50 | 51 | for (i = 0; i < length; i++) { 52 | sscanf(buf, "%02X", &u); 53 | bfconvert.bytes[i] = u; 54 | buf += 2; 55 | } 56 | 57 | return bfconvert.val; 58 | } 59 | 60 | 61 | void cov_log(long double ld, char* msg, char* fn) { 62 | int ld_size, i; 63 | unsigned char* buf; 64 | FILE* file; 65 | 66 | file = fopen(fn, "a"); 67 | ld_size = 10; 68 | buf = malloc(ld_size); 69 | 70 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 71 | cov_serialize(ld, buf, ld_size); 72 | for (i = 0; i < ld_size; i++) { 73 | fprintf(file, "%02X", buf[i]); 74 | } 75 | fprintf(file, "\n"); 76 | fclose(file); 77 | } 78 | 79 | void cov_spec_log(long double ideal, long double delta, char* fn) { 80 | cov_log(ideal, "ideal", fn); 81 | cov_log(delta, "delta", fn); 82 | } 83 | 84 | void cov_arr_log(long double lds[], int size, char* msg, char* fn) { 85 | int ld_size, i, j; 86 | unsigned char* buf; 87 | FILE *file; 88 | 89 | file = fopen(fn, "a"); 90 | ld_size = 10; 91 | buf = malloc(ld_size); 92 | 93 | if (strlen(msg) > 0) fprintf(file, "#%s\n", msg); 94 | for (i = 0; i < size; i++) { 95 | long double ld = lds[i]; 96 | cov_serialize(ld, buf, ld_size); 97 | if (i > 0) fprintf(file, " "); 98 | for (j = 0; j < ld_size; j++) { 99 | fprintf(file, "%02X", buf[j]); 100 | } 101 | } 102 | fprintf(file, "\n"); 103 | fclose(file); 104 | } 105 | 106 | void cov_spec_arr_log(long double ideal[], int size, long double delta, char* fn) { 107 | cov_arr_log(ideal, size, "ideal", fn); 108 | cov_log(delta, "delta", fn); 109 | } 110 | 111 | 112 | void cov_check(char* log, char* spec, char* result) { 113 | char line[80], estimate_hex[80], ideal_hex[80], delta_hex[80]; 114 | long double estimate, ideal, delta, diff; 115 | FILE *log_file, *spec_file, *result_file; 116 | int ld_size; 117 | 118 | ld_size = 10; 119 | 120 | // reading log file 121 | log_file = fopen(log, "rt"); 122 | while (fgets(line, 80, log_file) != NULL) { 123 | if (line[0] != '#') strcpy(estimate_hex, line); 124 | } 125 | fclose(log_file); 126 | 127 | spec_file = fopen(spec, "rt"); 128 | while (fgets(line, 80, spec_file) != NULL) { 129 | if (strncmp(line, "#ideal", 6) == 0) { 130 | fgets(ideal_hex, 80, spec_file); 131 | } else if (strncmp(line, "#delta", 6) == 0) { 132 | fgets(delta_hex, 80, spec_file); 133 | } 134 | } 135 | fclose(spec_file); 136 | 137 | // compare log and spec results 138 | estimate = cov_deserialize(estimate_hex, ld_size); 139 | ideal = cov_deserialize(ideal_hex, ld_size); 140 | delta = cov_deserialize(delta_hex, ld_size); 141 | 142 | if (estimate > ideal) diff = estimate - ideal; 143 | else diff = ideal - estimate; 144 | 145 | result_file = fopen(result, "w"); 146 | if (delta >= diff) fprintf(result_file, "true\n"); 147 | else fprintf(result_file, "false\n"); 148 | fclose(result_file); 149 | } 150 | 151 | void cov_arr_check(char* log, char* spec, int length) { 152 | char line[1000]; 153 | char *word, *sep, *brkt, *brkb; 154 | long double estimate[length], ideal[length], delta; 155 | FILE *log_file, *spec_file; 156 | int ld_size, cnt, i, predicate; 157 | 158 | sep = " "; 159 | ld_size = 10; 160 | 161 | // reading log file 162 | log_file = fopen(log, "rt"); 163 | while (fgets(line, 1000, log_file) != NULL) { 164 | if (line[0] != '#') { 165 | cnt = 0; 166 | for (word = strtok_r(line, sep, &brkt); 167 | word; 168 | word = strtok_r(NULL, sep, &brkt)){ 169 | estimate[cnt] = cov_deserialize(word, ld_size); 170 | cnt++; 171 | } 172 | } 173 | } 174 | fclose(log_file); 175 | 176 | // reading spec file 177 | spec_file = fopen(spec, "rt"); 178 | while (fgets(line, 1000, log_file) != NULL) { 179 | if (strncmp(line, "#ideal", 6) == 0) { 180 | cnt = 0; 181 | fgets(line, 1000, spec_file); 182 | for (word = strtok_r(line, sep, &brkb); 183 | word; 184 | word = strtok_r(NULL, sep, &brkb)){ 185 | ideal[cnt] = cov_deserialize(word, ld_size); 186 | cnt++; 187 | } 188 | } else if (strncmp(line, "#delta", 6) == 0) { 189 | fgets(line, 80, spec_file); 190 | delta = cov_deserialize(line, ld_size); 191 | } 192 | } 193 | fclose(spec_file); 194 | 195 | predicate = 1; 196 | for (i = 0; i < length; i++) { 197 | long double diff; 198 | if (estimate[i] > ideal[i]) diff = estimate[i] - ideal[i]; 199 | else diff = ideal[i] - estimate[i]; 200 | if (delta < diff) { 201 | predicate = 0; 202 | break; 203 | } 204 | } 205 | 206 | if (predicate) printf("true\n"); 207 | else printf("false\n"); 208 | } 209 | -------------------------------------------------------------------------------- /src/tests/test4/functions.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test4/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test4/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "a", 10 | "type": "float" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "b", 15 | "type": "float" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "c", 20 | "type": "longdouble" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "argc", 25 | "type": "int" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tests/test5/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test5/functions.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test5/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test5/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "a", 10 | "type": "double" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "b", 15 | "type": "float" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "c", 20 | "type": "longdouble" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "argc", 25 | "type": "int" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tests/test6/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test6/functions.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test6/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test6/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "x", 10 | "type": "longdouble[4]" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "y", 15 | "type": "double[2]" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "i", 20 | "type": "int" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "argc", 25 | "type": "int" 26 | }, 27 | "localVar": { 28 | "function": "main", 29 | "name": "result", 30 | "type": "longdouble" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/tests/test7/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test7/functions.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test7/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test7/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "x", 10 | "type": "longdouble[4]" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "y", 15 | "type": "float[2]" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "i", 20 | "type": "int" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "argc", 25 | "type": "int" 26 | }, 27 | "localVar": { 28 | "function": "main", 29 | "name": "result", 30 | "type": "longdouble" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/tests/test8/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test8/functions.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test8/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test8/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "c", 10 | "type": "double[4]" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "argc", 15 | "type": "int" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "n", 20 | "type": "int" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "result", 25 | "type": "longdouble" 26 | }, 27 | "localVar": { 28 | "function": "aprintf", 29 | "name": "a", 30 | "type": "pointer" 31 | }, 32 | "localVar": { 33 | "function": "aprintf", 34 | "name": "str", 35 | "type": "pointer" 36 | }, 37 | "localVar": { 38 | "function": "aprintf", 39 | "name": "i", 40 | "type": "int" 41 | }, 42 | "localVar": { 43 | "function": "aprintf", 44 | "name": "n", 45 | "type": "int" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/tests/test9/exclude.txt: -------------------------------------------------------------------------------- 1 | cov_log 2 | cov_check 3 | cov_arr_check 4 | cov_serialize 5 | cov_deserialize 6 | cov_spec_log 7 | cov_arr_log 8 | cov_spec_arr_log 9 | -------------------------------------------------------------------------------- /src/tests/test9/include.txt: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /src/tests/test9/searchFile.json: -------------------------------------------------------------------------------- 1 | {"config": [ 2 | {"localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "pointer" 6 | }}, 7 | {"localVar": { 8 | "function": "main", 9 | "name": "c", 10 | "type": ["float[4][2]", "double[4][2]", "longdouble[4][2]"] 11 | }}, 12 | {"localVar": { 13 | "function": "main", 14 | "name": "argc", 15 | "type": "int" 16 | }}, 17 | {"localVar": { 18 | "function": "main", 19 | "name": "n", 20 | "type": "int" 21 | }}, 22 | {"localVar": { 23 | "function": "main", 24 | "name": "result", 25 | "type": ["float", "double", "longdouble"] 26 | }}, 27 | {"localVar": { 28 | "function": "calculate", 29 | "name": "x", 30 | "type": ["float*", "double*", "longdouble*"] 31 | }}, 32 | {"localVar": { 33 | "function": "calculate", 34 | "name": "count", 35 | "type": ["float", "double", "longdouble"] 36 | }}, 37 | {"localVar": { 38 | "function": "calculate", 39 | "name": "i", 40 | "type": "int" 41 | }}, 42 | {"localVar": { 43 | "function": "calculate", 44 | "name": "n", 45 | "type": "int" 46 | }}, 47 | {"localVar": { 48 | "function": "aprintf", 49 | "name": "a", 50 | "type": ["float*", "double*", "longdouble*"] 51 | }}, 52 | {"localVar": { 53 | "function": "aprintf", 54 | "name": "str", 55 | "type": "pointer" 56 | }}, 57 | {"localVar": { 58 | "function": "aprintf", 59 | "name": "i", 60 | "type": "int" 61 | }}, 62 | {"localVar": { 63 | "function": "aprintf", 64 | "name": "n", 65 | "type": "int" 66 | }} 67 | ]} 68 | -------------------------------------------------------------------------------- /src/tests/test9/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "localVar": { 3 | "function": "main", 4 | "name": "argv", 5 | "type": "int**" 6 | }, 7 | "localVar": { 8 | "function": "main", 9 | "name": "c", 10 | "type": "longdouble[4][2]" 11 | }, 12 | "localVar": { 13 | "function": "main", 14 | "name": "argc", 15 | "type": "int" 16 | }, 17 | "localVar": { 18 | "function": "main", 19 | "name": "n", 20 | "type": "int" 21 | }, 22 | "localVar": { 23 | "function": "main", 24 | "name": "result", 25 | "type": "longdouble" 26 | }, 27 | "localVar": { 28 | "function": "calculate", 29 | "name": "x", 30 | "type": "longdouble*" 31 | }, 32 | "localVar": { 33 | "function": "calculate", 34 | "name": "count", 35 | "type": "longdouble" 36 | }, 37 | "localVar": { 38 | "function": "calculate", 39 | "name": "i", 40 | "type": "int" 41 | }, 42 | "localVar": { 43 | "function": "calculate", 44 | "name": "n", 45 | "type": "int" 46 | }, 47 | "localVar": { 48 | "function": "aprintf", 49 | "name": "a", 50 | "type": "longdouble*" 51 | }, 52 | "localVar": { 53 | "function": "aprintf", 54 | "name": "str", 55 | "type": "int*" 56 | }, 57 | "localVar": { 58 | "function": "aprintf", 59 | "name": "i", 60 | "type": "int" 61 | }, 62 | "localVar": { 63 | "function": "aprintf", 64 | "name": "n", 65 | "type": "int" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/tests/tests.py: -------------------------------------------------------------------------------- 1 | from ConfigParser import RawConfigParser 2 | from itertools import imap 3 | from SCons.Script import * 4 | from sets import Set 5 | 6 | def needsTestSuite(target): 7 | """check whether this target needs test suite details""" 8 | 9 | if str(target) == 'test': 10 | return True 11 | 12 | if str(target).startswith('test-'): 13 | return True 14 | 15 | if isinstance(target, str): 16 | target = Entry('#' + target) 17 | 18 | return False 19 | 20 | 21 | def Tests(env): 22 | """return sequence of all enabled tests, ordered by test number""" 23 | return sorted(env['tests'], key=lambda item: int(item.name[4:])) 24 | 25 | 26 | def generate(env): 27 | if 'tests' in env: 28 | return 29 | 30 | env['tests'] = set() 31 | env.AddMethod(Tests) 32 | 33 | # skip test suite details unless something actually needs them 34 | if not any(imap(needsTestSuite, BUILD_TARGETS)): 35 | return 36 | 37 | # simplified version uses sets instead of dictionaries 38 | for subdir in env.Glob('#src/tests/test*'): 39 | if not subdir.isdir(): 40 | continue 41 | 42 | env['tests'].add(subdir) 43 | 44 | 45 | def exists(env): 46 | return True 47 | --------------------------------------------------------------------------------