X-Git-Url: http://plrg.eecs.uci.edu/git/?p=cdsspec-compiler.git;a=blobdiff_plain;f=src%2Fedu%2Fuci%2Feecs%2FspecCompiler%2FcodeGenerator%2FCodeVariables.java;h=e6dfc1dae68cb5aef131ca6fc9520c5ef9fccee2;hp=3638194cea63aa86900ba41c5536adbd0bbbe2b2;hb=541ee814ad10bc181abd4d8825397249c6f86ad7;hpb=5fe4d211752fa05df28c1e2b2e17b69492d3a40b diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java index 3638194..e6dfc1d 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java @@ -1,78 +1,79 @@ package edu.uci.eecs.specCompiler.codeGenerator; import java.util.ArrayList; +import java.util.HashSet; +import java.io.File; +import edu.uci.eecs.specCompiler.grammerParser.ParseException; +import edu.uci.eecs.specCompiler.grammerParser.SpecParser; +import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct; +import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface; +import edu.uci.eecs.specCompiler.specExtraction.Construct; +import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader; import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct; import edu.uci.eecs.specCompiler.specExtraction.IDExtractor; import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct; +import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; +import edu.uci.eecs.specCompiler.specExtraction.ParserUtils; import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct; import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct; -import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar; import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor; +import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration; public class CodeVariables { // C++ code or library - public static final String HEADER_THREADS = "threads.h"; + public static final String HEADER_STDLIB = ""; + public static final String HEADER_THREADS = ""; + public static final String HEADER_STDINT = ""; public static final String ThreadIDType = "thrd_t"; public static final String GET_THREAD_ID = "thrd_current"; public static final String BOOLEAN = "bool"; public static final String UINT64 = "uint64_t"; // Model checker code - public static final String HEADER_CDSANNOTATE = "cdsannotate.h"; - public static final String HEADER_SPECANNOTATION = "specannotation.h"; - public static final String HEADER_CDSTRACE = "cdstrace.h"; - public static final String CDSAnnotate = "cdsannotate"; + public static final String HEADER_CDSANNOTATE = ""; + public static final String HEADER_COMMON = ""; + public static final String HEADER_SPECANNOTATION = ""; + public static final String HEADER_CDSTRACE = ""; +// public static final String CDSAnnotate = "cdsannotate"; + public static final String CDSAnnotate = "_Z11cdsannotatemPv"; public static final String CDSAnnotateType = "SPEC_ANALYSIS"; - public static final String GET_PREV_ATOMIC_VAL = "get_prev_value"; + public static final String IDType = "call_id_t"; public static final String SPEC_ANNO_TYPE = "spec_anno_type"; + public static final String SPEC_ANNO_TYPE_FUNC_TABLE_INIT = "FUNC_TABLE_INIT"; public static final String SPEC_ANNO_TYPE_HB_INIT = "HB_INIT"; public static final String SPEC_ANNO_TYPE_INTERFACE_BEGIN = "INTERFACE_BEGIN"; - public static final String SPEC_ANNO_TYPE_POST_CHECK = "POST_CHECK"; public static final String SPEC_ANNO_TYPE_HB_CONDITION = "HB_CONDITION"; public static final String SPEC_ANNO_TYPE_INTERFACE_END = "INTERFACE_END"; public static final String SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE = "POTENTIAL_CP_DEFINE"; + public static final String SPEC_ANNO_TYPE_CP_DEFINE_CHECK = "CP_DEFINE_CHECK"; + public static final String SPEC_ANNO_TYPE_CP_DEFINE = "CP_DEFINE"; public static final String SPEC_ANNOTATION = "spec_annotation"; public static final String SPEC_ANNOTATION_FIELD_TYPE = "type"; public static final String SPEC_ANNOTATION_FIELD_ANNO = "annotation"; + public static final String ANNO_FUNC_TABLE_INIT = "anno_func_table_init"; public static final String ANNO_HB_INIT = "anno_hb_init"; - public static final String ANNO_INTERFACE_BOUNDARY = "anno_interface_boundary"; - public static final String ANNO_ID = "anno_id"; + public static final String ANNO_INTERFACE_BEGIN = "anno_interface_begin"; + public static final String ANNO_INTERFACE_END = "anno_interface_end"; public static final String ANNO_POTENTIAL_CP_DEFINE = "anno_potentail_cp_define"; public static final String ANNO_CP_DEFINE = "anno_cp_define"; public static final String ANNO_CP_DEFINE_CHECK = "anno_cp_define_check"; public static final String ANNO_HB_CONDITION = "anno_hb_condition"; - public static final String ANNO_POST_CHECK = "anno_post_check"; // Specification variables - public static final String HEADER_SPEC_SEQUENTIAL = "_spec_sequential.h"; - public static final String SPEC_SEQUENTIAL_HEADER_MACRO = HEADER_SPEC_SEQUENTIAL - .replace('.', '_').toUpperCase(); - public static final String SPEC_SEQUENTIAL_STRUCT = "Sequential"; - public static final String SPEC_SEQUENTIAL_INSTANCE = "__sequential"; - - public static final String SPEC_CONDITION = "condition"; - public static final String SPEC_ID = "id"; - public static final String SPEC_INTERFACE = "interface"; - public static final String SPEC_INTERFACE_CALL_SEQUENCE = "interface_call_sequence"; - public static final String SPEC_GLOBAL_CALL_SEQUENCE = "global_call_sequence"; - public static final String SPEC_INTERFACE_WRAPPER = "__wrapper_"; - - public static final String VAR_ThreadID = "tid"; - public static final String VAR_CALL_SEQUENCE_NUM = "call_sequence_num"; + public static final String DEFAULT_ID = "0"; // Specification library + public static final String HEADER_SPEC_LIB = ""; public static final String SPEC_QUEUE = "spec_queue"; public static final String SPEC_STACK = "spec_stack"; public static final String SPEC_DEQUE = "spec_deque"; public static final String SPEC_HASHTABLE = "spec_hashtable"; - public static final String HEADER_SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable.h"; public static final String SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable"; - public static final String HEADER_SPEC_TAG = "spec_tag.h"; public static final String SPEC_TAG = "spec_tag"; public static final String SPEC_TAG_CURRENT = "current"; public static final String SPEC_TAG_NEXT = "next"; @@ -83,81 +84,18 @@ public class CodeVariables { public static final String MACRO_RETURN = "__RET__"; public static final String MACRO_ATOMIC_RETURN = "__ATOMIC_RET__"; - // Break the code (String) into multiple lines and add it to newCode - private static void breakCodeLines(ArrayList newCode, String code) { - int begin = 0, end = 0; - while (end < code.length()) { - if (code.charAt(end) == '\n') { - String line = code.substring(begin, end); - newCode.add(line); - begin = end + 1; - } - end++; - } - } - public static void printCode(ArrayList code) { for (int i = 0; i < code.size(); i++) { System.out.println(code.get(i)); } } - public static String getFuncName(String funcDecl) { - int beginIdx = funcDecl.indexOf('('); - IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx); - return idExtractor.getPrevID(); - } - - public static String getFuncReturnType(String funcDecl) { - int beginIdx = funcDecl.indexOf('('); - IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx); - idExtractor.getPrevID(); - int idLineBegin = idExtractor.lineBeginIdxOfID(), idBegin = idExtractor - .getIDBeginIdx(); - String type = funcDecl.substring(idLineBegin, idBegin); - return SpecExtractor.trimSpace(type); - } - - public static ArrayList getFuncArgs(String funcDecl) { - ArrayList args = new ArrayList(); - int beginIdx = funcDecl.indexOf('('), endIdx = funcDecl.indexOf(')'); - IDExtractor idExtractor = new IDExtractor(funcDecl, endIdx); - String arg = idExtractor.getPrevID(); - // Void argument - if (arg == null || idExtractor.getIDBeginIdx() < beginIdx) { - return args; - } else { - args.add(arg); - } - - do { - endIdx = funcDecl.lastIndexOf(',', endIdx); - if (endIdx == -1) { - return args; - } - idExtractor.reset(endIdx); - args.add(idExtractor.getPrevID()); - } while (true); - } - private static String COMMENT(String comment) { return "/* " + comment + " */"; } - private static String GET(String var) { - return "get(&" + VAR(var) + ", " + VAR_ThreadID + ")"; - } - - private static String PUT(String var, String tid, String val) { - return "put(&" + VAR(var) + ", " + tid + ", " + val + ");"; - } - - private static String INIT(String var) { - return "init(&" + VAR(var) + ");"; - } - private static String INCLUDE(String header) { - return "#include <" + header + ">"; + return "#include " + header; } private static String DEFINE(String left, String right) { @@ -168,28 +106,50 @@ public class CodeVariables { return "#undef " + macro; } - private static String VAR(String var) { - return SPEC_SEQUENTIAL_INSTANCE + "." + var; + private static String GET_FIELD_BY_PTR(String ptr, String field) { + return ptr + "->" + field; } - private static String BRACE(String val) { - return "(" + val + ")"; + private static String GET_FIELD(String var, String field) { + return var + "->" + field; } - private static String VAR_PTR(String var) { - return "&" + SPEC_SEQUENTIAL_INSTANCE + "." + var; + private static String BRACE(String val) { + return "(" + val + ")"; } private static String ASSIGN(String structName, String field, String val) { return structName + "." + field + " = " + val + ";"; } + private static String ASSIGN(String varName, String val) { + return varName + " = " + val + ";"; + } + private static String ASSIGN_PTR(String structName, String field, String val) { return structName + "." + field + " = &" + val + ";"; } - private static String DECLARE(String structType, String structName) { - return structType + " " + structName + ";"; + private static String ASSIGN_TO_PTR(String structName, String field, + String val) { + return structName + "->" + field + " = " + val + ";"; + } + + private static String ASSIGN_PTR_TO_PTR(String structName, String field, String val) { + return structName + "->" + field + " = &" + val + ";"; + } + + private static String STRUCT_NEW_DECLARE_DEFINE(String type, String name) { + return "struct " + type + " *" + name + " = (struct " + type + "*) malloc(sizeof(struct " + type + "));"; + } + + private static String DECLARE(String type, String name) { + return type + " " + name + ";"; + } + + private static String DECLARE(VariableDeclaration varDecl) { + String type = varDecl.type, name = varDecl.name; + return type + " " + name + ";"; } private static String DECLARE_DEFINE(String type, String var, String val) { @@ -197,113 +157,274 @@ public class CodeVariables { } private static String ANNOTATE(String structName) { - return CDSAnnotate + "(" + CDSAnnotateType + ", &" + structName + ");"; + return CDSAnnotate + "(" + CDSAnnotateType + ", " + structName + ");"; + } + + private static ArrayList DEFINE_INFO_STRUCT(String interfaceName, + FunctionHeader header) { + ArrayList code = new ArrayList(); + code.add("typedef struct " + interfaceName + "_info {"); + if (!header.returnType.equals("void")) { + code.add(DECLARE(header.returnType, MACRO_RETURN)); + } + for (int i = 0; i < header.args.size(); i++) { + code.add(DECLARE(header.args.get(i))); + } + code.add("} " + interfaceName + "_info;"); + return code; + } + + private static ArrayList DEFINE_ID_FUNC(String interfaceName, + String idCode) { + ArrayList code = new ArrayList(); + code.add("static " + IDType + " " + interfaceName + "_id() {"); + if (!idCode.equals("")) { + code.add(DECLARE_DEFINE(IDType, MACRO_ID, idCode)); + } else { + code.add(DECLARE_DEFINE(IDType, MACRO_ID, DEFAULT_ID)); + } + code.add("return " + MACRO_ID + ";"); + code.add("}"); + return code; + } + + private static ArrayList DEFINE_CHECK_ACTION_FUNC( + InterfaceConstruct construct, FunctionHeader header) { + String interfaceName = construct.name; + ArrayList code = new ArrayList(); + code.add("static bool " + interfaceName + "_check_action(void *info, " + + IDType + " " + MACRO_ID + ") {"); + code.add(DECLARE("bool", "check_passed")); + // Read info struct + if (!header.returnType.equals("void") || header.args.size() != 0) { + String infoStructType = interfaceName + "_info", infoStructName = "theInfo"; + code.add(DECLARE_DEFINE(infoStructType + "*", infoStructName, + BRACE(infoStructType + "*") + "info")); + if (!header.returnType.equals("void")) { + code.add((DECLARE_DEFINE(header.returnType, MACRO_RETURN, + GET_FIELD_BY_PTR(infoStructName, MACRO_RETURN)))); + } + for (int i = 0; i < header.args.size(); i++) { + String type = header.args.get(i).type, var = header.args.get(i).name; + code.add((DECLARE_DEFINE(type, var, + GET_FIELD_BY_PTR(infoStructName, var)))); + } + code.add(""); + } + // __COND_SAT + if (!construct.condition.equals("")) { + code.add(DECLARE_DEFINE("bool", MACRO_COND, construct.condition)); + } + // Check + if (!construct.check.equals("")) { + code.add(ASSIGN("check_passed", construct.check)); + code.add("if (!check_passed) return false;"); + } + // Action + if (construct.action.size() > 0) { + code.addAll(construct.action); + } + // Post_check + if (!construct.postCheck.equals("")) { + code.add(ASSIGN("check_passed", construct.postCheck)); + code.add("if (!check_passed) return false;"); + } + // Post_action + if (construct.postAction.size() > 0) { + code.addAll(construct.postAction); + } + // Return true finally + code.add("return true;"); + + code.add("}"); + + return code; + } + + private static HashSet getAllHeaders(SemanticsChecker semantics) { + HashSet headers = new HashSet(); + for (String interfaceName : semantics.interfaceName2Construct.keySet()) { + File f = semantics.interfaceName2Construct.get(interfaceName).file; + headers.addAll(semantics.srcFilesInfo.get(f).headers); + } + return headers; + } + + private static void makeFunctionStatic(ArrayList funcDefine) { + String headLine = funcDefine.get(0); + headLine = "static " + headLine; + funcDefine.set(0, headLine); + } + + private static String makeVariablesStatic(VariableDeclaration varDecl) { + String res = "static " + varDecl.type + " " + varDecl.name + ";"; + return res; + } + + private static FunctionHeader getFunctionHeader(SemanticsChecker semantics, + Construct construct) { + ArrayList content = semantics.srcFilesInfo.get(construct.file).content; + String headerLine = content.get(construct.beginLineNum); + if (headerLine.startsWith("template")) { + headerLine = content.get(construct.beginLineNum + 1); + } + headerLine = headerLine.substring(0, headerLine.indexOf(')') + 1); + try { + return SpecParser.parseFuncHeader(headerLine); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; } public static ArrayList generateGlobalVarDeclaration( SemanticsChecker semantics, GlobalConstruct construct) { ArrayList newCode = new ArrayList(); + HashSet allHeaders = getAllHeaders(semantics); - // Header conflicting avoidance macro & headers - newCode.add("/** @file " + HEADER_SPEC_SEQUENTIAL); - newCode.add(" * @brief Automatically generated header file for sequential variables"); - newCode.add(" */"); - newCode.add("#ifndef " + SPEC_SEQUENTIAL_HEADER_MACRO); - newCode.add("#define " + SPEC_SEQUENTIAL_HEADER_MACRO); + // All headers needed by the interface decalration + newCode.add(COMMENT("Include all the header files that contains the interface declaration")); + for (String header : allHeaders) { + newCode.add(INCLUDE(header)); + } newCode.add(""); - newCode.add(INCLUDE(HEADER_SPEC_PRIVATE_HASHTABLE)); + // Other necessary headers + newCode.add(INCLUDE(HEADER_STDLIB)); + newCode.add(INCLUDE(HEADER_STDINT)); + newCode.add(INCLUDE(HEADER_CDSANNOTATE)); + newCode.add(INCLUDE(HEADER_COMMON)); + newCode.add(INCLUDE(HEADER_SPEC_LIB)); newCode.add(INCLUDE(HEADER_SPECANNOTATION)); - newCode.add(INCLUDE(HEADER_SPEC_TAG)); newCode.add(""); - // Generate all sequential variables into a struct - newCode.add(COMMENT("Beginning of struct " + SPEC_SEQUENTIAL_STRUCT)); - newCode.add("typedef struct " + SPEC_SEQUENTIAL_STRUCT + " {"); - newCode.add(COMMENT("Condition")); - newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, SPEC_CONDITION)); - newCode.add(COMMENT("ID")); - newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, SPEC_ID)); - newCode.add(COMMENT("Current interface call")); - newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, SPEC_INTERFACE)); - newCode.add(COMMENT("Current interface call sequence")); - newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, - SPEC_INTERFACE_CALL_SEQUENCE)); - newCode.add(COMMENT("Global interface call sequence number")); - newCode.add(DECLARE(SPEC_TAG, SPEC_GLOBAL_CALL_SEQUENCE)); - newCode.add(""); - // DefineVar declaration + SequentialDefineSubConstruct code = construct.code; + // User-defined structs first + newCode.add(COMMENT("All other user-defined structs")); + ArrayList> declareStructs = code.declareStructs; + for (int i = 0; i < declareStructs.size(); i++) { + ArrayList declareStruct = declareStructs.get(i); + newCode.addAll(declareStruct); + newCode.add(""); + } + // User-defined variables + ArrayList varDecls = code.declareVar; + for (int i = 0; i < varDecls.size(); i++) { + VariableDeclaration varDecl = varDecls.get(i); + // Don't forget to make them static + newCode.add(makeVariablesStatic(varDecl)); + } + // User-defined functions + newCode.add(COMMENT("All other user-defined functions")); + ArrayList> defineFuncs = code.defineFuncs; + for (int i = 0; i < defineFuncs.size(); i++) { + ArrayList defineFunc = defineFuncs.get(i); + makeFunctionStatic(defineFunc); + newCode.addAll(defineFunc); + newCode.add(""); + } + for (String interfaceName : semantics.interfaceName2Construct.keySet()) { - InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct + InterfaceConstruct iConstruct = semantics.interfaceName2Construct .get(interfaceName); - ArrayList defineVars = iConstruct.action.defineVars; - if (defineVars.size() > 0) { - newCode.add(COMMENT("DefineVar in " + interfaceName)); - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, - var.getNewVarName())); - } + FunctionHeader funcHeader = getFunctionHeader(semantics, iConstruct); + // Define necessary info structure + if (!funcHeader.returnType.equals("void") + || funcHeader.args.size() > 0) { + newCode.add(COMMENT("Definition of interface info struct: " + + interfaceName)); + newCode.addAll(DEFINE_INFO_STRUCT(interfaceName, funcHeader)); + newCode.add(COMMENT("End of info struct definition: " + + interfaceName)); + newCode.add(""); } + + // Define ID function + newCode.add(COMMENT("ID function of interface: " + interfaceName)); + newCode.addAll(DEFINE_ID_FUNC(interfaceName, iConstruct.idCode)); + newCode.add(COMMENT("End of ID function: " + interfaceName)); newCode.add(""); - } - // Generate user-defined variable declaration - newCode.add(COMMENT("Beginnint of other user-defined variables")); - SequentialDefineSubConstruct globalCode = construct.code; - breakCodeLines(newCode, globalCode.declareVar); - newCode.add(COMMENT("End of other user-defined variables")); - // End of struct Sequential - newCode.add("} " + SPEC_SEQUENTIAL_STRUCT + "; " - + COMMENT("End of struct " + SPEC_SEQUENTIAL_STRUCT)); - // Generate definition of the sequential struct - newCode.add(""); - newCode.add(COMMENT("Instance of the struct")); - newCode.add(DECLARE(SPEC_SEQUENTIAL_STRUCT, SPEC_SEQUENTIAL_INSTANCE)); + // Define check_action function + newCode.add(COMMENT("Check action function of interface: " + + interfaceName)); + newCode.addAll(DEFINE_CHECK_ACTION_FUNC(iConstruct, funcHeader)); + newCode.add(COMMENT("End of check action function: " + + interfaceName)); + newCode.add(""); + } + // Interface function pointer table + String interfaceSize = Integer + .toString(semantics.interfaceName2Construct.size()); + newCode.add(DEFINE("INTERFACE_SIZE", interfaceSize)); + newCode.add(DECLARE("void**", "func_ptr_table")); newCode.add(""); newCode.add(COMMENT("Define function for sequential code initialization")); - newCode.add("void " + SPEC_SEQUENTIAL_INSTANCE + "_init() {"); - // Internal variables - newCode.add(COMMENT("Init internal variables")); - newCode.add(INIT(SPEC_CONDITION)); - newCode.add(INIT(SPEC_ID)); - newCode.add(INIT(SPEC_INTERFACE)); - newCode.add(INIT(SPEC_INTERFACE_CALL_SEQUENCE)); - newCode.add(INIT(SPEC_GLOBAL_CALL_SEQUENCE)); - // Init DefineVars - newCode.add(COMMENT("Init DefineVars")); + newCode.add("static void __sequential_init() {"); + // Init func_ptr_table + newCode.add(COMMENT("Init func_ptr_table")); + newCode.add(ASSIGN("func_ptr_table", + "(void**) malloc(sizeof(void*) * " + semantics.interface2Num.size() + " * 2)")); for (String interfaceName : semantics.interfaceName2Construct.keySet()) { - InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct - .get(interfaceName); - ArrayList defineVars = iConstruct.action.defineVars; - if (defineVars.size() > 0) { - newCode.add(COMMENT("DefineVar in " + interfaceName)); - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add(INIT(var.getNewVarName())); - } - } + String interfaceNum = Integer.toString(semantics.interface2Num + .get(interfaceName)); + newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + "]", + "(void*) &" + interfaceName + "_id")); + newCode.add(ASSIGN("func_ptr_table[2 * " + interfaceNum + " + 1]", + "(void*) &" + interfaceName + "_check_action")); } - // Init user-defined variables - newCode.add(COMMENT("Init user-defined variables")); - breakCodeLines(newCode, globalCode.initVar); - // Pass the HB initialization - newCode.add(COMMENT("Pass the happens-before initialization here")); - newCode.addAll(CodeVariables.generateHBInitAnnotation(semantics)); - // End of init the function - newCode.add("} " + COMMENT("End of init function")); - - // Generate the user-defined sequential functions newCode.add(""); - newCode.add(COMMENT("All other user-defined functions")); - breakCodeLines(newCode, globalCode.defineFunc); + // Init user-defined variables + newCode.addAll(construct.code.initVar); + // Pass function table info + newCode.add(COMMENT("Pass function table info")); + String structName = "anno_func_table_init", anno = "func_init"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_FUNC_TABLE_INIT, structName)); + newCode.add(ASSIGN_TO_PTR(structName, "size", "INTERFACE_SIZE")); + newCode.add(ASSIGN_TO_PTR(structName, "table", "func_ptr_table")); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_FUNC_TABLE_INIT)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); - // The end - newCode.add(""); - newCode.add("#endif " + SPEC_SEQUENTIAL_HEADER_MACRO + "\t" - + COMMENT("End of " + HEADER_SPEC_SEQUENTIAL)); + // Pass Happens-before relationship + newCode.addAll(generateHBInitAnnotation(semantics)); + newCode.add("}"); + newCode.add(COMMENT("End of Global construct generation in class")); - // printCode(newCode); + printCode(newCode); + return newCode; + } + + public static ArrayList generateStaticVarDefine( + SemanticsChecker semantics, GlobalConstruct construct) { + ArrayList newCode = new ArrayList(); + String className = semantics.getClassName(); + if (className == null) + return newCode; // No need to define any static variables + String templateList = semantics.getTemplateStr(); + String varPrefix; + if (templateList == null) { + varPrefix = className + "::"; + } else { + varPrefix = className + templateList + "::"; + } + String templateDecl = semantics.getTemplateFullStr(); + if (templateList == null) { + newCode.add(DECLARE("void**", varPrefix + "func_ptr_table")); + for (int i = 0; i < construct.code.declareVar.size(); i++) { + VariableDeclaration varDecl = construct.code.declareVar.get(i); + newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name)); + } + } else { + newCode.add(templateDecl); + newCode.add(DECLARE("void**", varPrefix + "func_ptr_table")); + for (int i = 0; i < construct.code.declareVar.size(); i++) { + VariableDeclaration varDecl = construct.code.declareVar.get(i); + newCode.add(templateDecl); + newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name)); + } + } return newCode; } @@ -328,20 +449,20 @@ public class CodeVariables { .get(right.hbConditionLabel)); newCode.add(COMMENT(left + " -> " + right)); - newCode.add(ANNO_HB_INIT + " " + structVarName + ";"); - newCode.add(ASSIGN(structVarName, "interface_num_before", + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_INIT, structVarName)); + newCode.add(ASSIGN_TO_PTR(structVarName, "interface_num_before", interfaceNumBefore)); - newCode.add(ASSIGN(structVarName, "hb_condition_num_before", + newCode.add(ASSIGN_TO_PTR(structVarName, "hb_condition_num_before", hbLabelNumBefore)); - newCode.add(ASSIGN(structVarName, "interface_num_after", + newCode.add(ASSIGN_TO_PTR(structVarName, "interface_num_after", interfaceNumAfter)); - newCode.add(ASSIGN(structVarName, "hb_condition_num_after", + newCode.add(ASSIGN_TO_PTR(structVarName, "hb_condition_num_after", hbLabelNumAfter)); - newCode.add(DECLARE(SPEC_ANNOTATION, annotationVarName)); - newCode.add(ASSIGN(annotationVarName, + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, annotationVarName)); + newCode.add(ASSIGN_TO_PTR(annotationVarName, SPEC_ANNOTATION_FIELD_TYPE, SPEC_ANNO_TYPE_HB_INIT)); - newCode.add(ASSIGN_PTR(annotationVarName, + newCode.add(ASSIGN_TO_PTR(annotationVarName, SPEC_ANNOTATION_FIELD_ANNO, structVarName)); newCode.add(ANNOTATE(annotationVarName)); } @@ -349,181 +470,234 @@ public class CodeVariables { return newCode; } + public static ArrayList generateEntryPointInitCall() { + ArrayList newCode = new ArrayList(1); + newCode.add("__sequential_init();"); + return newCode; + } + public static ArrayList generateInterfaceWrapper( SemanticsChecker semantics, InterfaceConstruct construct) { ArrayList newCode = new ArrayList(); - String funcDecl = construct.interfaceDeclBody.substring(0, - construct.interfaceDeclBody.indexOf(')') + 1); - String returnType = getFuncReturnType(funcDecl), funcName = getFuncName(funcDecl), renamedFuncName = SPEC_INTERFACE_WRAPPER - + funcName; - ArrayList args = getFuncArgs(funcDecl); - + String interfaceName = construct.name; // Generate necessary header file (might be redundant but never mind) - newCode.add(COMMENT("Automatically generated code for interface: " - + construct.name)); - newCode.add(COMMENT("Include redundant headers")); - newCode.add(INCLUDE(HEADER_THREADS)); + newCode.add(INCLUDE(HEADER_STDLIB)); newCode.add(INCLUDE(HEADER_CDSANNOTATE)); newCode.add(INCLUDE(HEADER_SPECANNOTATION)); - newCode.add(INCLUDE(HEADER_SPEC_TAG)); - newCode.add(INCLUDE(HEADER_SPEC_PRIVATE_HASHTABLE)); - newCode.add(""); + newCode.add(INCLUDE(HEADER_SPEC_LIB)); + + FunctionHeader header = getFunctionHeader(semantics, construct); + String interfaceNum = Integer.toString(semantics.interface2Num + .get(construct.name)); + // Rename the interface + renameInterface(semantics, construct); + InterfaceDefineConstruct defineConstruct = semantics.interfaceName2DefineConstruct + .get(interfaceName); + if (defineConstruct != null) { + renameInterface(semantics, defineConstruct); + } // Generate wrapper header - newCode.add(COMMENT("Wrapper for " + SPEC_INTERFACE_WRAPPER + funcName)); - breakCodeLines(newCode, funcDecl); - newCode.add("{"); - + // If it's not in a class, we should declare the wrapper function + if (semantics.getClassName() == null) { + FunctionHeader renamedHeader = header + .getRenamedHeader(SPEC_INTERFACE_WRAPPER); + newCode.add(COMMENT("Declaration of the wrapper")); + newCode.add(renamedHeader + ";"); + newCode.add(""); + } + newCode.add(header.toString() + " {"); // Wrapper function body - newCode.add(DECLARE_DEFINE(ThreadIDType, VAR_ThreadID, GET_THREAD_ID - + BRACE(""))); - newCode.add(DECLARE_DEFINE(UINT64, VAR_CALL_SEQUENCE_NUM, - SPEC_TAG_CURRENT + BRACE(VAR_PTR(SPEC_GLOBAL_CALL_SEQUENCE)))); - newCode.add(SPEC_TAG_NEXT + BRACE(VAR_PTR(SPEC_GLOBAL_CALL_SEQUENCE))); - newCode.add(PUT(SPEC_INTERFACE_CALL_SEQUENCE, VAR_ThreadID, - VAR_CALL_SEQUENCE_NUM)); + newCode.add(COMMENT("Interface begins")); // Interface begin - newCode.add(""); - newCode.add(COMMENT("Interface begin")); - String interfaceName = construct.name; - String annoStruct = "interface_boundary", interfaceNum = Integer - .toString(semantics.interface2Num.get(interfaceName)); - newCode.add(DECLARE(ANNO_INTERFACE_BOUNDARY, annoStruct)); - newCode.add(ASSIGN(annoStruct, "interface_num", interfaceNum)); - newCode.add(ASSIGN(annoStruct, "call_sequence_num", - VAR_CALL_SEQUENCE_NUM)); + String structName = "interface_begin"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_BEGIN, "interface_begin")); + newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); String anno = "annotation_interface_begin"; - newCode.add(DECLARE(SPEC_ANNOTATION, anno)); - newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE, - SPEC_ANNO_TYPE_INTERFACE_BEGIN)); - newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct)); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_BEGIN)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); newCode.add(ANNOTATE(anno)); // Call original renamed function - String funcCall = renamedFuncName + "("; - if (args.size() == 0) { - funcCall = funcCall + ")"; + if (header.returnType.equals("void")) { + newCode.add(header.getRenamedCall(SPEC_INTERFACE_WRAPPER) + ";"); } else { - funcCall = funcCall + args.get(0); - for (int i = 1; i < args.size(); i++) { - funcCall = funcCall + ", " + args.get(i); - } - funcCall = funcCall + ")"; - } - newCode.add(DECLARE_DEFINE(returnType, MACRO_RETURN, funcCall)); - newCode.add(DECLARE_DEFINE("int", MACRO_COND, GET(SPEC_CONDITION))); - newCode.add(DECLARE_DEFINE(UINT64, MACRO_ID, GET(SPEC_ID))); - // Post check & action - newCode.add(""); - newCode.add(COMMENT("Post_check action, define macros for all DefineVars")); - // Define all DefineVar macro - ArrayList defineVars = construct.action.defineVars; - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add(DEFINE(var.varName, BRACE(GET(interfaceName + "_" - + var.varName)))); - } - // Post check - newCode.add(DECLARE_DEFINE("bool", "post_check_passed", - construct.postCheck)); - annoStruct = "post_check"; - newCode.add(DECLARE(ANNO_POST_CHECK, annoStruct)); - newCode.add(ASSIGN(annoStruct, "check_passed", "post_check_passed")); - newCode.add(ASSIGN(annoStruct, "interface_num", interfaceNum)); - newCode.add(ASSIGN(annoStruct, "call_sequence_num", - VAR_CALL_SEQUENCE_NUM)); - anno = "annotation_post_check"; - newCode.add(DECLARE(SPEC_ANNOTATION, anno)); - newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE, - SPEC_ANNO_TYPE_POST_CHECK)); - newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct)); - newCode.add(ANNOTATE(anno)); - // Post action if any - breakCodeLines(newCode, construct.postAction); - // Undefine all DefineVar macro - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add(UNDEFINE(var.varName)); + newCode.add(DECLARE_DEFINE(header.returnType, MACRO_RETURN, + header.getRenamedCall(SPEC_INTERFACE_WRAPPER))); } // HB conditions - newCode.add(""); for (String label : construct.hbConditions.keySet()) { - String hbCondition = construct.hbConditions.get(label); - newCode.add(COMMENT("Happens-before condition for " + label - + " ::= " + hbCondition)); - newCode.add("if " + BRACE(hbCondition) + " {"); - String hbNum = Integer.toString(semantics.hbLabel2Num.get(label)); - annoStruct = "hb_condition" + hbNum; - newCode.add(DECLARE(ANNO_HB_CONDITION, annoStruct)); - newCode.add(ASSIGN(annoStruct, "interface_num", interfaceNum)); - newCode.add(ASSIGN(annoStruct, "hb_condition_num", hbNum)); - newCode.add(ASSIGN(annoStruct, "id", MACRO_ID)); - newCode.add(ASSIGN(annoStruct, "call_sequence_num", - VAR_CALL_SEQUENCE_NUM)); + String condition = construct.hbConditions.get(label); + String hbCondNum = Integer.toString(semantics.hbLabel2Num + .get(label)); + newCode.add("if " + BRACE(condition) + " {"); + structName = "hb_condition"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName)); + newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); + + newCode.add(ASSIGN_TO_PTR(structName, "hb_condition_num", hbCondNum)); + anno = "annotation_hb_condition"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); + newCode.add(""); + } + // Also add the true condition if any + if (semantics.containsConditionalInterface(new ConditionalInterface(interfaceName, ""))) { + structName = "hb_condition"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName)); + newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); + newCode.add(ASSIGN_TO_PTR(structName, "hb_condition_num", "0")); anno = "annotation_hb_condition"; - newCode.add(DECLARE(SPEC_ANNOTATION, anno)); - newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE, - SPEC_ANNO_TYPE_HB_CONDITION)); - newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct)); - ANNOTATE(anno); - newCode.add("} " + COMMENT("End of HB condition " + label)); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); newCode.add(""); } // Interface end - annoStruct = "interface_boundary"; - anno = "annotation_interface_end"; - newCode.add(DECLARE(SPEC_ANNOTATION, anno)); - newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE, - SPEC_ANNO_TYPE_INTERFACE_END)); - newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct)); + String infoStructType = null, infoName = null; + if (!header.returnType.equals("void") || header.args.size() > 0) { + infoStructType = interfaceName + "_info"; + infoName = "info"; + newCode.add(DECLARE_DEFINE(infoStructType + "*", infoName, + BRACE(infoStructType + "*") + " malloc(sizeof(" + + infoStructType + "))")); + if (!header.returnType.equals("void")) { + newCode.add(ASSIGN_TO_PTR(infoName, MACRO_RETURN, MACRO_RETURN)); + } + for (int i = 0; i < header.args.size(); i++) { + String argName = header.args.get(i).name; + newCode.add(ASSIGN_TO_PTR(infoName, argName, argName)); + } + } else { + infoName = "NULL"; + } + structName = "interface_end"; + anno = "annoation_interface_end"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_END, structName)); + newCode.add(ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); + newCode.add(ASSIGN_TO_PTR(structName, "info", infoName)); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_END)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); newCode.add(ANNOTATE(anno)); - + // Return __RET__ if it's not void + if (!header.returnType.equals("void")) { + newCode.add("return " + MACRO_RETURN + ";"); + } // End of the wrapper function - newCode.add("} " - + COMMENT("End of automatically generated code for interface wrapper")); + newCode.add("}"); - printCode(newCode); + // printCode(newCode); return newCode; } + // Rename the interface depending on if it's declaration or definition + public static void renameInterface(SemanticsChecker semantics, + Construct construct) { + FunctionHeader header = getFunctionHeader(semantics, construct); + ArrayList content = semantics.srcFilesInfo.get(construct.file).content; + int lineNum = construct.beginLineNum; + String headerLine = content.get(construct.beginLineNum); + if (headerLine.startsWith("template")) { + headerLine = content.get(construct.beginLineNum + 1); + lineNum++; + } + String newLine = header.getRenamedHeader(SPEC_INTERFACE_WRAPPER) + .toString() + " {"; + content.set(lineNum, newLine); + } + + public static void addAtomicReturn(SemanticsChecker semantics, + Construct construct) { + int lineNum = construct.beginLineNum - 1; + ArrayList content = semantics.srcFilesInfo.get(construct.file).content; + String oldLine = content.get(lineNum); + String newLine = "uint64_t " + MACRO_ATOMIC_RETURN + " = " + oldLine; + content.set(lineNum, newLine); + } + public static ArrayList generatePotentialCPDefine( SemanticsChecker semantics, PotentialCPDefineConstruct construct) { ArrayList newCode = new ArrayList(); - + // Add atomic return variable if the predicate accesses to it + if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) { + addAtomicReturn(semantics, construct); + } // Generate redundant header files newCode.add(COMMENT("Automatically generated code for potential commit point: " + construct.label)); newCode.add(COMMENT("Include redundant headers")); - newCode.add(INCLUDE(HEADER_THREADS)); - newCode.add(INCLUDE(HEADER_CDSTRACE)); - newCode.add(INCLUDE(HEADER_SPEC_PRIVATE_HASHTABLE)); - newCode.add(INCLUDE(HEADER_SPEC_SEQUENTIAL)); + newCode.add(INCLUDE(HEADER_STDINT)); + newCode.add(INCLUDE(HEADER_CDSANNOTATE)); + newCode.add(INCLUDE(HEADER_SPECANNOTATION)); + newCode.add(""); + // Add annotation + newCode.add("if (" + construct.condition + ") {"); + String structName = "potential_cp_define", anno = "annotation_potential_cp_define"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_POTENTIAL_CP_DEFINE, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + newCode.add(ASSIGN_TO_PTR(structName, "label_num", labelNum)); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); + return newCode; + } + + public static ArrayList generateCPDefineCheck( + SemanticsChecker semantics, CPDefineCheckConstruct construct) { + ArrayList newCode = new ArrayList(); + // Add atomic return variable if the predicate accesses to it + if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) { + addAtomicReturn(semantics, construct); + } + // Generate redundant header files + newCode.add(COMMENT("Automatically generated code for commit point define check: " + + construct.label)); + newCode.add(COMMENT("Include redundant headers")); + newCode.add(INCLUDE(HEADER_STDINT)); + newCode.add(INCLUDE(HEADER_CDSANNOTATE)); newCode.add(""); - // Some necessary function calls - newCode.add(DECLARE_DEFINE(ThreadIDType, VAR_ThreadID, GET_THREAD_ID - + BRACE(""))); - newCode.add(DECLARE_DEFINE(UINT64, MACRO_ATOMIC_RETURN, - GET_PREV_ATOMIC_VAL + BRACE(VAR_ThreadID))); - newCode.add("if " + BRACE(construct.condition) + " {"); - newCode.add(DECLARE_DEFINE(UINT64, VAR_CALL_SEQUENCE_NUM, - GET(SPEC_INTERFACE_CALL_SEQUENCE))); - String annoStruct = "potential_cp_define"; - newCode.add(DECLARE(ANNO_POTENTIAL_CP_DEFINE, annoStruct)); - newCode.add(ASSIGN(annoStruct, "interface_num", GET(SPEC_INTERFACE))); + // Add annotation + newCode.add("if (" + construct.condition + ") {"); + String structName = "cp_define_check", anno = "annotation_cp_define_check"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE_CHECK, structName)); String labelNum = Integer.toString(semantics.commitPointLabel2Num .get(construct.label)); - newCode.add(ASSIGN(annoStruct, "label_num", labelNum)); - newCode.add(ASSIGN(annoStruct, "call_sequence_num", - VAR_CALL_SEQUENCE_NUM)); - String anno = "annotation_potential_cp_define"; - newCode.add(DECLARE(SPEC_ANNOTATION, anno)); - newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE, - SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE)); - newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct)); - ANNOTATE(anno); - - newCode.add("} " - + COMMENT("End of automatically generated code for potential commit point")); + newCode.add(ASSIGN_TO_PTR(structName, "label_num", labelNum)); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE_CHECK)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); + return newCode; + } + public static ArrayList generateCPDefine( + SemanticsChecker semantics, CPDefineConstruct construct) { + ArrayList newCode = new ArrayList(); + // Generate redundant header files + newCode.add(COMMENT("Automatically generated code for commit point define check: " + + construct.label)); + newCode.add(""); + // Add annotation + newCode.add("if (" + construct.condition + ") {"); + String structName = "cp_define", anno = "annotation_cp_define"; + newCode.add(STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + newCode.add(ASSIGN_TO_PTR(structName, "label_num", labelNum)); + newCode.add(STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add(ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE)); + newCode.add(ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add(ANNOTATE(anno)); + newCode.add("}"); return newCode; } }