Пример #1
0
 def addCallees(symbolName, routineName):
     for call in self.callsByCallerName.get(routineName, []):
         if call.getAttribute("caller") != routineName:
             raise Exception(
                 "unexpected error when constructing callgraph for symbol aliases"
             )
         argumentsInCall = [
             argument.getAttribute("symbolName")
             for argument in call.getElementsByTagName("argument")
         ]
         argIndex = -1
         try:
             argIndex = argumentsInCall.index(symbolName)
         except Exception:
             pass
         if argIndex < 0:
             continue
         calleeName = call.getAttribute("callee")
         if calleeName in aliasNamesByRoutineName:
             raise Exception(
                 "unsupported case: symbol %s is passed into routine %s in multiple paths in the callgraph"
                 % (symbolName, calleeName))
         calleeRoutine = self.routinesByName[calleeName]
         argumentsInCallee = [
             argument.getAttribute("symbolName") for argument in
             calleeRoutine.getElementsByTagName("argument")
         ]
         if len(argumentsInCall) != len(argumentsInCallee):
             raise Exception(
                 "call to %s in %s doesn't have the expected number of arguments"
                 % (calleeName, routineName))
         aliasName = argumentsInCallee[argIndex]
         aliasNamesByRoutineName[calleeName] = aliasName
         addCallees(aliasName, calleeName)
Пример #2
0
    def __init__(self, doc):
        def getCallIndexByAttribute(attributeName):
            index = {}
            for call in doc.getElementsByTagName("call"):
                identifier = call.getAttribute(attributeName)
                callList = index.get(identifier, [])
                callList.append(call)
                index[identifier] = callList
            return index

        routinesByName = {}
        for routine in doc.getElementsByTagName("routine"):
            routineName = routine.getAttribute("name")
            if routineName in routinesByName:
                raise UsageError(
                    "Duplicate subroutines found with name %s. Subroutines need to have unique names in Hybrid Fortran."
                    % (routineName))
            routinesByName[routineName] = routine

        callsByCalleeName = getCallIndexByAttribute("callee")
        callsByCallerName = getCallIndexByAttribute("caller")
        callGraphEdgesByCallerName = {}
        callGraphEdgesByCalleeName = {}

        def addCallees(routineName):
            for call in callsByCallerName.get(routineName, []):
                callerName = call.getAttribute("caller")
                if callerName != routineName:
                    raise Exception(
                        "unexpected error when constructing callgraph")
                calleeName = call.getAttribute("callee")
                edgeList = callGraphEdgesByCallerName.get(routineName, [])
                edgeList.append((callerName, calleeName))
                callGraphEdgesByCallerName[routineName] = edgeList
                edgeList = callGraphEdgesByCalleeName.get(calleeName, [])
                edgeList.append((callerName, calleeName))
                callGraphEdgesByCalleeName[calleeName] = edgeList
                addCallees(calleeName)

        callGraphRootRoutineNames = [
            routineName for routineName in routinesByName.keys()
            if len(callsByCalleeName.get(routineName, [])) == 0
        ]
        for routineName in callGraphRootRoutineNames:
            addCallees(routineName)

        #at this point we should have the complete callgraph
        self.callGraphEdgesByCallerName = callGraphEdgesByCallerName
        self.routinesByName = routinesByName
        self.callsByCalleeName = callsByCalleeName
        self.callsByCallerName = callsByCallerName
        self.doc = doc
        self.symbolsNode = createOrGetFirstNodeWithName('symbols', doc)
Пример #3
0
 def addCallees(routineName):
     for call in callsByCallerName.get(routineName, []):
         callerName = call.getAttribute("caller")
         if callerName != routineName:
             raise Exception("unexpected error when constructing callgraph")
         calleeName = call.getAttribute("callee")
         edgeList = callGraphEdgesByCallerName.get(routineName, [])
         edgeList.append((callerName, calleeName))
         callGraphEdgesByCallerName[routineName] = edgeList
         edgeList = callGraphEdgesByCalleeName.get(calleeName, [])
         edgeList.append((callerName, calleeName))
         callGraphEdgesByCalleeName[calleeName] = edgeList
         addCallees(calleeName)
Пример #4
0
    def __init__(self, doc):
        def getCallIndexByAttribute(attributeName):
            index = {}
            for call in doc.getElementsByTagName("call"):
                identifier = call.getAttribute(attributeName)
                callList = index.get(identifier, [])
                callList.append(call)
                index[identifier] = callList
            return index

        routinesByName = {}
        for routine in doc.getElementsByTagName("routine"):
            routineName = routine.getAttribute("name")
            if routineName in routinesByName:
                raise UsageError("Duplicate subroutines found with name %s. Subroutines need to have unique names in Hybrid Fortran." %(routineName))
            routinesByName[routineName] = routine

        callsByCalleeName = getCallIndexByAttribute("callee")
        callsByCallerName = getCallIndexByAttribute("caller")
        callGraphEdgesByCallerName = {}
        callGraphEdgesByCalleeName = {}

        def addCallees(routineName):
            for call in callsByCallerName.get(routineName, []):
                callerName = call.getAttribute("caller")
                if callerName != routineName:
                    raise Exception("unexpected error when constructing callgraph")
                calleeName = call.getAttribute("callee")
                edgeList = callGraphEdgesByCallerName.get(routineName, [])
                edgeList.append((callerName, calleeName))
                callGraphEdgesByCallerName[routineName] = edgeList
                edgeList = callGraphEdgesByCalleeName.get(calleeName, [])
                edgeList.append((callerName, calleeName))
                callGraphEdgesByCalleeName[calleeName] = edgeList
                addCallees(calleeName)

        callGraphRootRoutineNames = [
            routineName
            for routineName in routinesByName.keys()
            if len(callsByCalleeName.get(routineName, [])) == 0
        ]
        for routineName in callGraphRootRoutineNames:
            addCallees(routineName)

        #at this point we should have the complete callgraph
        self.callGraphEdgesByCallerName = callGraphEdgesByCallerName
        self.routinesByName = routinesByName
        self.callsByCalleeName = callsByCalleeName
        self.callsByCallerName = callsByCallerName
        self.doc = doc
        self.symbolsNode = createOrGetFirstNodeWithName('symbols', doc)
Пример #5
0
 def addCallees(routineName):
     for call in callsByCallerName.get(routineName, []):
         callerName = call.getAttribute("caller")
         if callerName != routineName:
             raise Exception(
                 "unexpected error when constructing callgraph")
         calleeName = call.getAttribute("callee")
         edgeList = callGraphEdgesByCallerName.get(routineName, [])
         edgeList.append((callerName, calleeName))
         callGraphEdgesByCallerName[routineName] = edgeList
         edgeList = callGraphEdgesByCalleeName.get(calleeName, [])
         edgeList.append((callerName, calleeName))
         callGraphEdgesByCalleeName[calleeName] = edgeList
         addCallees(calleeName)
Пример #6
0
 def addCallees(symbolName, routineName):
     for call in self.callsByCallerName.get(routineName, []):
         if call.getAttribute("caller") != routineName:
             raise Exception(
                 "unexpected error when constructing callgraph for symbol aliases"
             )
         argumentsInCall = [
             argument.getAttribute("symbolName")
             for argument in call.getElementsByTagName("argument")
         ]
         argIndex = -1
         try:
             argIndex = argumentsInCall.index(symbolName)
         except Exception:
             pass
         if argIndex < 0:
             continue
         calleeName = call.getAttribute("callee")
         if calleeName in aliasNamesByRoutineName:
             raise Exception(
                 "unsupported case: symbol %s is passed into routine %s in multiple paths in the callgraph" %(
                     symbolName, calleeName
                 )
             )
         calleeRoutine = self.routinesByName[calleeName]
         argumentsInCallee = [
             argument.getAttribute("symbolName")
             for argument in calleeRoutine.getElementsByTagName("argument")
         ]
         if len(argumentsInCall) != len(argumentsInCallee):
             raise Exception(
                 "call to %s in %s doesn't have the expected number of arguments" %(
                     calleeName,
                     routineName
                 )
             )
         aliasName = argumentsInCallee[argIndex]
         aliasNamesByRoutineName[calleeName] = aliasName
         addCallees(aliasName, calleeName)