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=0ee2ee0c9e7c13eee1261db84ae7f1ca92108658;hp=4ee3e3dd09f4523b29d7d41a0b726bf147f9db6f;hb=d37341bf7e15cffc4367435b89dc94736dbe72d1;hpb=d9c5f3639af2eaa7a35b7242c846f657b875657c diff --git a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java index 4ee3e3d..0ee2ee0 100644 --- a/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java +++ b/src/edu/uci/eecs/specCompiler/codeGenerator/CodeVariables.java @@ -1,235 +1,918 @@ package edu.uci.eecs.specCompiler.codeGenerator; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.io.File; +import edu.uci.eecs.specCompiler.grammerParser.utilParser.UtilParser; +import edu.uci.eecs.specCompiler.grammerParser.utilParser.ParseException; +import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct; +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.InterfaceConstruct; +import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct; +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.VariableDeclaration; +/** + *

Defines a list of commonly used constant strings.

+ * @author peizhaoo + * + */ public class CodeVariables { // C++ code or library - public static final String HEADER_threads = "threads.h"; - public static final String ThreadIDType = "thrd_t"; - public static final String GET_THREAD_ID = "thrd_current"; + public static final String HEADER_STDLIB = ""; + public static final String HEADER_THREADS = ""; + public static final String HEADER_STDINT = ""; + public static final String HEADER_MODELMEMORY = ""; + public static final String HEADER_MODELTYPES = ""; + public static final String ThreadIDType = "thread_id_t"; 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_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 = "cdsannotate"; public static final String CDSAnnotateType = "SPEC_ANALYSIS"; - // It's a SPEC_TAG type, it has current() and next() function - public static final String INTERFACE_CALL_SEQUENCE = "__interface_call_sequence"; + public static final String IDType = "call_id_t"; - public static final String SPEC_ANNOTATION_TYPE = "spec_anno_type"; + public static final String SPEC_ANNO_TYPE = "spec_anno_type"; + public static final String SPEC_ANNO_TYPE_INIT = "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_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_CLEAR = "CP_CLEAR"; + 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_INIT = "anno_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_POTENTIAL_CP_DEFINE = "anno_potentail_cp_define"; + 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_potential_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_CP_CLEAR = "anno_cp_clear"; 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 SPEC_SEQUENTIAL_HEADER = "_spec_sequential.h"; - public static final String SPEC_SEQUENTIAL_HEADER_MACRO = SPEC_SEQUENTIAL_HEADER - .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_INTERFACE_WRAPPER = "__wrapper_"; + 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 SPEC_PRIVATE_HASHTABLE_HEADER = "spec_private_hashtable.h"; public static final String SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable"; public static final String SPEC_TAG = "spec_tag"; + public static final String SPEC_TAG_CURRENT = "current"; + public static final String SPEC_TAG_NEXT = "next"; // Macro public static final String MACRO_ID = "__ID__"; public static final String MACRO_COND = "__COND_SAT__"; public static final String MACRO_RETURN = "__RET__"; + public static final String MACRO_ATOMIC_RETURN = "__ATOMIC_RET__"; + public static final String MACRO_THREAD_ID = "__TID__"; + + public static void printCode(ArrayList code) { + for (int i = 0; i < code.size(); i++) { + System.out.println(code.get(i)); + } + } + + private static String COMMENT(String comment) { + return "/* " + comment + " */"; + } + + private static String SHORT_COMMENT(String comment) { + return " // " + comment; + } + + private static String INCLUDE(String header) { + return "#include " + header; + } + + private static String DEFINE(String left, String right) { + return "#define " + left + " " + right; + } + + private static String UNDEFINE(String macro) { + return "#undef " + macro; + } + + private static String GET_FIELD_BY_PTR(String ptr, String field) { + return ptr + "->" + field; + } + + private static String GET_FIELD(String var, String field) { + return var + "->" + field; + } + + 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 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) { + return type + " " + var + " = " + val + ";"; + } + + private static String ANNOTATE(SemanticsChecker semantics, String structName) { + return CDSAnnotate + "(" + CDSAnnotateType + ", " + structName + ");"; + } - // 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; + 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( + InterfaceConstruct construct, FunctionHeader header) { + String interfaceName = construct.name; + ArrayList code = new ArrayList(); + String idCode = construct.idCode; + code.add("inline static " + IDType + " " + interfaceName + "_id(" + + "void *info, " + ThreadIDType + " " + MACRO_THREAD_ID + ") {"); + + // Read info struct + if (!header.returnType.equals("void") || header.args.size() != 0) { + String infoStructType = interfaceName + "_info", infoStructName = "theInfo"; + code.add(DECLARE_DEFINE("\t" + infoStructType + "*", + infoStructName, BRACE(infoStructType + "*") + "info")); + if (!header.returnType.equals("void")) { + code.add((DECLARE_DEFINE("\t" + 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("\t" + + (DECLARE_DEFINE(type, var, + GET_FIELD_BY_PTR(infoStructName, var)))); } - end++; + code.add(""); } + + if (!idCode.equals("")) { + code.add("\t" + DECLARE_DEFINE(IDType, MACRO_ID, idCode)); + } else { + code.add("\t" + DECLARE_DEFINE(IDType, MACRO_ID, DEFAULT_ID)); + } + code.add("\treturn " + MACRO_ID + ";"); + code.add("}"); + return code; } - private static void printCode(ArrayList code) { - for (int i = 0; i < code.size(); i++) { - System.out.println(code.get(i)); + private static ArrayList DEFINE_CHECK_ACTION_FUNC( + InterfaceConstruct construct, FunctionHeader header) { + String interfaceName = construct.name; + ArrayList code = new ArrayList(); + code.add("inline static bool " + interfaceName + + "_check_action(void *info, " + IDType + " " + MACRO_ID + ", " + + ThreadIDType + " " + MACRO_THREAD_ID + ") {"); + code.add("\t" + DECLARE("bool", "check_passed")); + // Read info struct + if (!header.returnType.equals("void") || header.args.size() != 0) { + String infoStructType = interfaceName + "_info", infoStructName = "theInfo"; + code.add("\t" + + DECLARE_DEFINE(infoStructType + "*", infoStructName, + BRACE(infoStructType + "*") + "info")); + if (!header.returnType.equals("void")) { + code.add("\t" + + (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("\t" + + (DECLARE_DEFINE(type, var, + GET_FIELD_BY_PTR(infoStructName, var)))); + } + code.add(""); + } + // __COND_SAT + if (!construct.condition.equals("")) { + code.add("\t" + + DECLARE_DEFINE("bool", MACRO_COND, construct.condition)); + } + // Check + if (!construct.check.equals("")) { + code.add("\t" + ASSIGN("check_passed", construct.check)); + code.add("\tif (!check_passed)"); + code.add("\t\treturn false;"); + + } + // Action + if (construct.action.size() > 0) { + addAllCodeWithIndent(code, construct.action, "\t"); } + // Post_check + if (!construct.postCheck.equals("")) { + code.add("\t" + ASSIGN("check_passed", construct.postCheck)); + code.add("\tif (!check_passed)"); + code.add("\t\treturn false;"); + } + // Post_action + if (construct.postAction.size() > 0) { + addAllCodeWithIndent(code, construct.postAction, "\t"); + } + // Return true finally + code.add("\treturn true;"); + + code.add("}"); + + return code; } - + + private static void addAllCodeWithIndent(ArrayList allCode, + ArrayList target, String indent) { + for (int i = 0; i < target.size(); i++) { + allCode.add(indent + target.get(i)); + } + } + + public 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); + } + headers.add(HEADER_STDLIB); + headers.add(HEADER_STDINT); + headers.add(HEADER_MODELMEMORY); + headers.add(HEADER_MODELTYPES); + headers.add(HEADER_SPEC_LIB); + headers.add(HEADER_STDINT); + headers.add(HEADER_CDSANNOTATE); + // headers.add(HEADER_COMMON); + headers.add(HEADER_SPECANNOTATION); + return headers; + } + + private static void makeFunctionStatic(ArrayList funcDefine) { + String headLine = funcDefine.get(0); + headLine = "inline 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 + 1), templateLine = null; + if (headerLine.startsWith("template")) { + templateLine = headerLine; + headerLine = content.get(construct.beginLineNum + 2); + } + headerLine = headerLine.substring(0, headerLine.indexOf(')') + 1); + try { + FunctionHeader header = UtilParser.parseFuncHeader(headerLine); + if (templateLine != null) { + ArrayList templateArgs = UtilParser + .getTemplateArg(templateLine); + header.setTemplateList(templateArgs); + } + return header; + } 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 " + SPEC_SEQUENTIAL_HEADER); - 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); - newCode.add("#include " + "<" + SPEC_PRIVATE_HASHTABLE_HEADER + ">"); - newCode.add("#include " + "<" + HEADER_SPECANNOTATION + ">"); - - // Generate all sequential variables into a struct - newCode.add("/* Beginning of struct " + SPEC_SEQUENTIAL_STRUCT + " */"); - newCode.add("typedef struct " + SPEC_SEQUENTIAL_STRUCT + " {"); - newCode.add("/* Condition of interface */"); - newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_CONDITION + ";"); - newCode.add("/* ID of interface */"); - newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_ID + ";"); - newCode.add("/* Current interface call */"); - newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_INTERFACE + ";"); - newCode.add("/* Current interface call sequence */"); - newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_INTERFACE_CALL_SEQUENCE - + ";"); - newCode.add(""); - // DefineVar declaration - for (String interfaceName : semantics.interfaceName2Construct.keySet()) { - InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct - .get(interfaceName).construct; - ArrayList defineVars = iConstruct.action.defineVars; - newCode.add("/* DefineVar in " + interfaceName + " */"); - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add(SPEC_PRIVATE_HASHTABLE + " " + var.getNewVarName() - + ";"); - } + 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(""); } - // Generate user-defined variable declaration - newCode.add("/* Beginnint of other user-defined variables */"); - SequentialDefineSubConstruct globalCode = construct.code; - breakCodeLines(newCode, globalCode.declareVar); - newCode.add("/* End of other user-defined variables */"); - // End of struct Sequential - newCode.add("} " + SPEC_SEQUENTIAL_STRUCT + "; /* End of struct " - + SPEC_SEQUENTIAL_STRUCT + " */"); - // Generate - - // Generate code from the DefineVar, __COND_SAT__ and __ID__ - // The hashtable in the contract can only contains pointers or integers - // __COND_SAT__ - newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_CONDITION - + ";"); - // __ID__ - newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_ID + ";"); - // DefineVars for (String interfaceName : semantics.interfaceName2Construct.keySet()) { - InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct - .get(interfaceName).construct; - ArrayList defineVars = iConstruct.action.defineVars; - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add(CodeVariables.SPEC_HASHTABLE + var.getNewVarName() - + ";"); + InterfaceConstruct iConstruct = semantics.interfaceName2Construct + .get(interfaceName); + 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(iConstruct, funcHeader)); + newCode.add(COMMENT("End of ID function: " + interfaceName)); + newCode.add(""); + + // 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 - newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_INTERFACE - + ";"); - // __interface_call_sequence - newCode.add(CodeVariables.SPEC_HASHTABLE - + CodeVariables.SPEC_INTERFACE_CALL_SEQUENCE + ";"); - // Interface call sequence varaiable - newCode.add(CodeVariables.SPEC_TAG + " " - + CodeVariables.INTERFACE_CALL_SEQUENCE + ";"); - // End of the struct - newCode.add("}"); + // Interface function pointer table + String interfaceSize = Integer + .toString(semantics.interfaceName2Construct.size()); + newCode.add(DEFINE("INTERFACE_SIZE", interfaceSize)); + // Make it static + newCode.add("static " + DECLARE("void**", "func_ptr_table")); + // Happens-before initialization rules + // Should make it static + newCode.add("static " + DECLARE(ANNO_HB_INIT + "**", "hb_init_table")); - // FIXME: Constructor should be modified and put in the right place - // Generate constructor (the place to initialize everything!) - breakCodeLines(newCode, globalCode.initVar); - // __COND_SAT__ - newCode.add("init_table(&" + CodeVariables.SPEC_CONDITION + ");"); - // __ID__ - newCode.add("init_table(&" + CodeVariables.SPEC_ID + ");"); - // DefineVars + newCode.add(""); + newCode.add(COMMENT("Define function for sequential code initialization")); + newCode.add("inline static void __sequential_init() {"); + // Init func_ptr_table + newCode.add("\t" + COMMENT("Init func_ptr_table")); + newCode.add("\t" + + 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).construct; - ArrayList defineVars = iConstruct.action.defineVars; - for (int i = 0; i < defineVars.size(); i++) { - DefineVar var = defineVars.get(i); - newCode.add("init_table(&" + var.getNewVarName() + ");"); - } + String interfaceNum = Integer.toString(semantics.interface2Num + .get(interfaceName)); + newCode.add("\t" + + ASSIGN("func_ptr_table[2 * " + interfaceNum + "]", + "(void*) &" + interfaceName + "_id")); + newCode.add("\t" + + ASSIGN("func_ptr_table[2 * " + interfaceNum + " + 1]", + "(void*) &" + interfaceName + "_check_action")); } - // __interface - newCode.add("init_table(&" + CodeVariables.SPEC_INTERFACE + ");"); - // __interface_call_sequence - newCode.add("init_table(&" + CodeVariables.SPEC_INTERFACE_CALL_SEQUENCE - + ");"); + // Init Happens-before rules table + newCode.addAll(generateHBInitAnnotation(semantics)); - // Pass the happens-before relationship check here - newCode.addAll(CodeVariables.generateHBInitAnnotation(semantics)); + // Pass init info, including function table info & HB rules + newCode.add("\t" + + COMMENT("Pass init info, including function table info & HB rules")); + String structName = "anno_init", anno = "init"; + newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(ANNO_INIT, structName)); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "func_table", "func_ptr_table")); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "func_table_size", "INTERFACE_SIZE")); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "hb_init_table", "hb_init_table")); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "hb_init_table_size", + "HB_INIT_TABLE_SIZE")); + newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t" + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INIT)); + newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t" + ANNOTATE(semantics, anno)); - newCode.add("\n"); + newCode.add(""); + // Init user-defined variables + addAllCodeWithIndent(newCode, construct.code.initVar, "\t"); - // Generate the sequential functions - breakCodeLines(newCode, globalCode.defineFunc); + newCode.add("}"); + newCode.add(COMMENT("End of Global construct generation in class")); - // The end - newCode.add("#endif " + SPEC_SEQUENTIAL_HEADER_MACRO + "\t/* End of " - + SPEC_SEQUENTIAL_HEADER + " */"); + // printCode(newCode); + return newCode; + } - printCode(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")); + newCode.add(DECLARE("anno_hb_init**", varPrefix + "hb_init_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")); + newCode.add(templateDecl); + newCode.add(DECLARE("anno_hb_init**", varPrefix + "hb_init_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; } - public static ArrayList generateHBInitAnnotation( + private static ArrayList generateHBInitAnnotation( SemanticsChecker semantics) { ArrayList newCode = new ArrayList(); + int hbConditionInitIdx = 0; for (ConditionalInterface left : semantics.getHBConditions().keySet()) { for (ConditionalInterface right : semantics.getHBConditions().get( left)) { String structVarName = "hbConditionInit" + hbConditionInitIdx; + // String annotationVarName = "hb_init" + hbConditionInitIdx; hbConditionInitIdx++; - int interfaceNumBefore = semantics.interface2Num - .get(left.interfaceName), hbLabelNumBefore = semantics.hbLabel2Num - .get(left.hbConditionLabel), interfaceNumAfter = semantics.interface2Num - .get(right.interfaceName), hbLabelNumAfter = semantics.hbLabel2Num - .get(right.hbConditionLabel); - newCode.add(ANNO_HB_INIT + " " + structVarName + ";"); - - newCode.add(structVarName + "." + "interface_num_before" - + " = " + interfaceNumBefore + ";"); - newCode.add(structVarName + "." + "hb_condition_num_before" - + " = " + hbLabelNumBefore + ";"); - newCode.add(structVarName + "." + "interface_num_after" + " = " - + interfaceNumAfter + ";"); - newCode.add(structVarName + "." + "hb_condition_num_after" - + " = " + hbLabelNumAfter + ";"); - - newCode.add(CDSAnnotate + "(" + CDSAnnotateType + ", &" - + structVarName + ");"); + String interfaceNumBefore = Integer + .toString(semantics.interface2Num + .get(left.interfaceName)), hbLabelNumBefore = Integer + .toString(semantics.hbLabel2Num + .get(left.hbConditionLabel)), interfaceNumAfter = Integer + .toString(semantics.interface2Num + .get(right.interfaceName)), hbLabelNumAfter = Integer + .toString(semantics.hbLabel2Num + .get(right.hbConditionLabel)); + newCode.add("\t" + COMMENT(left + " -> " + right)); + + newCode.add("\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_INIT, structVarName)); + newCode.add("\t" + + ASSIGN_TO_PTR(structVarName, "interface_num_before", + interfaceNumBefore) + + SHORT_COMMENT(left.interfaceName)); + newCode.add("\t" + + ASSIGN_TO_PTR(structVarName, + "hb_condition_num_before", hbLabelNumBefore) + + SHORT_COMMENT(left.hbConditionLabel)); + newCode.add("\t" + + ASSIGN_TO_PTR(structVarName, "interface_num_after", + interfaceNumAfter) + + SHORT_COMMENT(right.interfaceName)); + newCode.add("\t" + + ASSIGN_TO_PTR(structVarName, + "hb_condition_num_after", hbLabelNumAfter) + + SHORT_COMMENT(right.hbConditionLabel)); + } + } + // Init hb_init_table + newCode.add("\t" + COMMENT("Init hb_init_table")); + newCode.add("\t" + + ASSIGN("hb_init_table", "(" + ANNO_HB_INIT + + "**) malloc(sizeof(" + ANNO_HB_INIT + "*) * " + + hbConditionInitIdx + ")")); + // Define HB_INIT_TABLE_SIZE + newCode.add("\t" + + DEFINE("HB_INIT_TABLE_SIZE", + Integer.toString(hbConditionInitIdx))); + for (int i = 0; i < hbConditionInitIdx; i++) { + newCode.add("\t" + + ASSIGN("hb_init_table[" + i + "]", "hbConditionInit" + i)); + } + return newCode; + } + + public static ArrayList generateEntryPointInitCall() { + ArrayList newCode = new ArrayList(); + newCode.add("\t" + "__sequential_init();"); + return newCode; + } + + public static ArrayList generateInterfaceWrapperDeclaration( + SemanticsChecker semantics, InterfaceConstruct construct) { + FunctionHeader header = getFunctionHeader(semantics, construct); + ArrayList declaration = new ArrayList(); + declaration.add(header.getRenamedHeader(SPEC_INTERFACE_WRAPPER) + .getDeclaration() + ";"); + return declaration; + } + + // Only generate the definition of the wrapper, don't do any renaming + public static ArrayList generateInterfaceWrapperDefinition( + SemanticsChecker semantics, InterfaceConstruct construct) { + ArrayList newCode = new ArrayList(); + String interfaceName = construct.name; + + FunctionHeader header = getFunctionHeader(semantics, construct); + String interfaceNum = Integer.toString(semantics.interface2Num + .get(construct.name)); + + newCode.add(header.getTemplateFullStr()); + newCode.add(header.getFuncStr() + " {"); + // Wrapper function body + newCode.add("\t" + COMMENT("Interface begins")); + // Interface begin + String structName = "interface_begin"; + newCode.add("\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_BEGIN, + "interface_begin")); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum) + + SHORT_COMMENT(construct.name)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "interface_name", "\"" + construct.name + "\"")); + + String anno = "annotation_interface_begin"; + newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_BEGIN)); + newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t" + ANNOTATE(semantics, anno)); + // Call original renamed function + if (header.returnType.equals("void")) { + newCode.add("\t" + header.getRenamedCall(SPEC_INTERFACE_WRAPPER) + + ";"); + } else { + newCode.add("\t" + + DECLARE_DEFINE(header.returnType, MACRO_RETURN, + header.getRenamedCall(SPEC_INTERFACE_WRAPPER))); + } + // HB conditions + for (String label : construct.hbConditions.keySet()) { + String condition = construct.hbConditions.get(label); + String hbCondNum = Integer.toString(semantics.hbLabel2Num + .get(label)); + newCode.add("\t" + "if " + BRACE(condition) + " {"); + structName = "hb_condition"; + newCode.add("\t\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName)); + newCode.add("\t\t" + + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum) + + SHORT_COMMENT(construct.name)); + + newCode.add("\t\t" + + ASSIGN_TO_PTR(structName, "hb_condition_num", hbCondNum)); + anno = "annotation_hb_condition"; + newCode.add("\t\t" + + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION)); + newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t\t" + ANNOTATE(semantics, anno)); + newCode.add("\t" + "}"); + newCode.add(""); + } + // Also add the true condition if any + if (semantics.containsConditionalInterface(new ConditionalInterface( + interfaceName, ""))) { + structName = "hb_condition"; + newCode.add("\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName)); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum) + + SHORT_COMMENT(construct.name)); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "hb_condition_num", "0")); + anno = "annotation_hb_condition"; + newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION)); + newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t" + ANNOTATE(semantics, anno)); + newCode.add(""); + } + // Interface end + String infoStructType = null, infoName = null; + if (!header.returnType.equals("void") || header.args.size() > 0) { + infoStructType = interfaceName + "_info"; + infoName = "info"; + newCode.add("\t" + + DECLARE_DEFINE(infoStructType + "*", infoName, + BRACE(infoStructType + "*") + " malloc(sizeof(" + + infoStructType + "))")); + if (!header.returnType.equals("void")) { + newCode.add("\t" + + 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("\t" + ASSIGN_TO_PTR(infoName, argName, argName)); } + } else { + infoName = "NULL"; + } + structName = "interface_end"; + anno = "annoation_interface_end"; + newCode.add("\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_END, structName)); + newCode.add("\t" + + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum) + + SHORT_COMMENT(construct.name)); + newCode.add("\t" + ASSIGN_TO_PTR(structName, "info", infoName)); + newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_END)); + newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t" + ANNOTATE(semantics, anno)); + // Return __RET__ if it's not void + if (!header.returnType.equals("void")) { + newCode.add("\t" + "return " + MACRO_RETURN + ";"); + } + // End of the wrapper function + newCode.add("}"); + + // printCode(newCode); + return newCode; + } + + // Rename the interface name for 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(); + String oldLine = content.get(lineNum + 1); + + if (construct instanceof InterfaceConstruct) { + InterfaceConstruct iConstruct = (InterfaceConstruct) construct; + InterfaceDefineConstruct defineConstruct = semantics.interfaceName2DefineConstruct + .get(iConstruct.name); + if (defineConstruct != null) { // There is a defineConstruct + newLine = newLine + " ;"; + renameInterface(semantics, defineConstruct); + } else { // This is a declare & define construct + if (oldLine.indexOf('{') != -1) + newLine = newLine + " {"; + } + } else { + if (oldLine.indexOf('{') != -1) + newLine = newLine + " {"; + } + + content.set(lineNum + 1, 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("\t" + + COMMENT("Automatically generated code for potential commit point: " + + construct.label)); + newCode.add(""); + // Add annotation + newCode.add("\t" + "if (" + construct.condition + ") {"); + String structName = "potential_cp_define", anno = "annotation_potential_cp_define"; + newCode.add("\t\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_POTENTIAL_CP_DEFINE, + structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_name", "\"" + construct.label + "\"")); + newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t\t" + + ASSIGN_TO_PTR(anno, "type", + SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE)); + newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t\t" + ANNOTATE(semantics, anno)); + newCode.add("\t" + "}"); + return newCode; + } + + public static String getCPInterfaceNum(SemanticsChecker semantics, String commitPointLabel) { + HashMap cp2Interface = semantics.CPLabel2InterfaceConstruct; + InterfaceConstruct iConstruct = cp2Interface.get(commitPointLabel); + String interfaceName = iConstruct.name; + String interfaceNum = Integer.toString(semantics.interface2Num + .get(interfaceName)); + return interfaceNum; + } + + /** + *

+ * Commit point define check should be unique to each interface, meaning that they + * are not shared between different interfaces + *

+ * + * @param semantics + * @param construct + * @return + */ + 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("\t" + + COMMENT("Automatically generated code for commit point define check: " + + construct.label)); + newCode.add(""); + // Add annotation + + newCode.add("\t" + "if (" + construct.condition + ") {"); + String structName = "cp_define_check", anno = "annotation_cp_define_check"; + newCode.add("\t\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE_CHECK, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + String interfaceNum = getCPInterfaceNum(semantics, construct.label); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_name", "\"" + construct.label + "\"")); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); + newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE_CHECK)); + newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t\t" + ANNOTATE(semantics, anno)); + newCode.add("\t" + "}"); + return newCode; + } + + /** + *

+ * Commit point define check should be unique to each interface, meaning that they + * are not shared between different interfaces + *

+ * + * @param semantics + * @param construct + * @return + */ + public static ArrayList generateCPClear( + SemanticsChecker semantics, CPClearConstruct 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("\t" + + COMMENT("Automatically generated code for commit point clear: " + + construct.label)); + newCode.add(""); + // Add annotation + + newCode.add("\t" + "if (" + construct.condition + ") {"); + String structName = "cp_clear", anno = "annotation_cp_clear"; + newCode.add("\t\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_CLEAR, structName)); +// String labelNum = Integer.toString(semantics.commitPointLabel2Num +// .get(construct.label)); +// String interfaceNum = getCPInterfaceNum(semantics, construct.label); +// newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum)); +// newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); + newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_CLEAR)); + newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t\t" + ANNOTATE(semantics, anno)); + newCode.add("\t" + "}"); + return newCode; + } + + /** + *

+ * Commit point define should be unique to each interface, meaning that they + * are not shared between different interfaces + *

+ * + * @param semantics + * @param construct + * @return + */ + public static ArrayList generateCPDefine( + SemanticsChecker semantics, CPDefineConstruct construct) { + ArrayList newCode = new ArrayList(); + // Generate redundant header files + newCode.add("\t" + + COMMENT("Automatically generated code for commit point define: " + + construct.label)); + newCode.add(""); + // Add annotation + newCode.add("\t" + "if (" + construct.condition + ") {"); + String structName = "cp_define", anno = "annotation_cp_define"; + newCode.add("\t\t" + + STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE, structName)); + String labelNum = Integer.toString(semantics.commitPointLabel2Num + .get(construct.label)); + String interfaceNum = getCPInterfaceNum(semantics, construct.label); + String potentialLabelNum = Integer + .toString(semantics.commitPointLabel2Num + .get(construct.potentialCPLabel)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_name", "\"" + construct.label + "\"")); + newCode.add("\t\t" + + ASSIGN_TO_PTR(structName, "potential_cp_label_num", + potentialLabelNum)); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "potential_label_name", "\"" + construct.potentialCPLabel + "\"")); + newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)); + newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno)); + newCode.add("\t\t" + + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE)); + newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName)); + newCode.add("\t\t" + ANNOTATE(semantics, anno)); + newCode.add("\t" + "}"); return newCode; } }