def createAsmCode(loadRegisterIndex, valueTargets): asmString = "profile r%d,[" % loadRegisterIndex firstTarget = True for target in valueTargets: targetThread = instruction.getThreadIndex(target) targetInst = instruction.getInstIndex(target) if (firstTarget): asmString += "0x%X" % (target) else: asmString += "/0x%X" % (target) firstTarget = False asmString += "]" return asmString
def generateIntermediateProg(orgProg, profileEnable, storeTable, verbosity): outProg = dict() for thread in orgProg: outProg[thread] = [] sortedInstList = sorted(orgProg[thread].keys()) if (verbosity > 0): print("Thread %d: %s" % (thread, sortedInstList)) for sortedInst in sortedInstList: asm = orgProg[thread][sortedInst] # 1. Write original asm code if (instruction.getInstType(asm) == 1): # store # append store identifier outProg[thread].append( asm + ",0x%X" % instruction.getMemOp(thread, sortedInst)) else: outProg[thread].append(asm) # 2. Write instrumented asm code if (profileEnable and instruction.getInstType(asm) == 0): # See parse_prog.py for assembly code examples tokens = asm.split(",") assert (len(tokens) > 1) registerString = tokens[1] assert (registerString[0] == "r") registerIndex = int(registerString[1:]) addressString = tokens[0].split(" ")[1] addressInt = int(addressString, 16) valueTargets = [instruction.getMemOp(0xffff, addressInt) ] # initial memory value # # TODO: Smarter store-target filtering # Some targets are invalid and can be decided statically # if addressInt in storeTable: mostRecentIntraIndex = None for storeTarget in storeTable[addressInt]: if (instruction.getThreadIndex(storeTarget) != thread): # Inter-thread candidate stores valueTargets.append(storeTarget) else: # NOTE: Assume that store indices are sorted in ascending order storeIntraIndex = instruction.getInstIndex( storeTarget) if (storeIntraIndex < sortedInst): mostRecentIntraIndex = storeIntraIndex if (mostRecentIntraIndex != None): valueTargets.append( instruction.getMemOp(thread, mostRecentIntraIndex)) profileAsm = createAsmCode(registerIndex, valueTargets) #print(profileAsm) outProg[thread].append(profileAsm) return outProg
instruction.getMemId(bThreadIndex, bInstIndex))) for registerIndex in hist[executionIndex][thread]: for loadIndex in range( len(hist[executionIndex][thread][registerIndex])): loadValue = hist[executionIndex][thread][registerIndex][ loadIndex] #if (instruction.getThreadIndex(loadValue) == 0xffff): # # load value from initial memory values (not from store) # continue # find which load instruction corresponds to this load index assert (loadIndex < len( lookupInstFromLoad[thread][registerIndex])) instIndex = lookupInstFromLoad[thread][registerIndex][ loadIndex] aThreadIndex = instruction.getThreadIndex(loadValue) aInstIndex = instruction.getInstIndex(loadValue) bThreadIndex = thread bInstIndex = instIndex address = instruction.getAddress( prog[bThreadIndex][bInstIndex]) if (not args.single_copy_atomicity and aThreadIndex == bThreadIndex): # Load value is from a store in the same thread # This dependency is ignored in multiple-copy atomicity... assert (aThreadIndex != 0xffff) if (not args.no_dot): # Draw this edge in a different color in dot graph. graphFP.write( "%s -> %s [color=\"cyan\"];\n" % (instruction.getMemId(aThreadIndex, aInstIndex), instruction.getMemId(bThreadIndex, bInstIndex)))
def setDependencyPropagation(depSet): # Convert the set into a flat set flatSet = dict() # a dict which uses thread+inst as index for thread in depSet: for inst in depSet[thread]: memIndex = instruction.getMemOp(thread, inst) flatSet[memIndex] = set(depSet[thread][inst]) numInsts = len(flatSet) visited = dict() for memIndex in flatSet: visited[memIndex] = False visitedCount = 0 readyList = [] while True: #print("readyList %s" % readyList) if (len(readyList) == 0): # Add instructions with no unvisited dependent instructions for memIndex in flatSet: if (not visited[memIndex]): ready = True for depMemIndex in flatSet[memIndex]: if not visited[depMemIndex]: ready = False break if ready: readyList.append(memIndex) # Check if there is no added instruction if (len(readyList) == 0): if (visitedCount == numInsts): # All instructions in the thread are propagated break else: # There is unvisited instruction(s) print("Error: Cyclic dependency") print("numInsts %d visitedCount %d" % (numInsts, visitedCount)) print("visited %s" % visited) for memIndex in flatSet: if (not visited[memIndex]): sys.stdout.write("%X:" % memIndex) for depMemIndex in flatSet[memIndex]: #sys.stdout.write(" %X" % depMemIndex) if (not visited[depMemIndex]): sys.stdout.write(" %X" % depMemIndex) sys.stdout.write("\n") sys.exit(1) else: visitMemIndex = readyList.pop(0) visited[visitMemIndex] = True visitedCount += 1 #print("picked visitMemIndex %X" % visitMemIndex) #print("dependency %s" % flatSet[visitMemIndex]) addedSet = set() for depMemIndex in flatSet[visitMemIndex]: addedSet |= flatSet[depMemIndex] flatSet[visitMemIndex] |= addedSet # Convert back the flat set to the original hierarchical data structure for memIndex in flatSet: thread = instruction.getThreadIndex(memIndex) inst = instruction.getInstIndex(memIndex) depSet[thread][inst] = flatSet[memIndex] return depSet
0/0#ld 0x3,r9 0/1#st 0x2#0 0/2#ld 0x2,r10#0#1 """ if (args.gen_program): progFileName = "%s/%s" % (summaryDirPrefix, args.prog_file) woFileName = "%s/%s" % (summaryDirPrefix, args.wo_file) progFP = open(progFileName, "w") woFP = open(woFileName, "w") for thread in range(numThreads): for inst in range(len(insts[thread])): instructionLine = "%d/%d#%s" % (thread, inst, insts[thread][inst].getAssembly()) for intraDep in insts[thread][inst].intraDeps: intraDepInstIndex = instruction.getInstIndex(intraDep) instructionLine += ("#%d" % (intraDepInstIndex)) instructionLine += "\n" progFP.write(instructionLine) if (orderStSt): # NOTE: Current implementation does not handle memory barriers woDict = dict() for inst in range(len(insts[thread])): # [thread id]/[memory location]#[inst idx 1]#[inst idx 2]#... # No line if memory location is not used at all if (insts[thread][inst].instType == 1): address = insts[thread][inst].address assert (address != -1) if (not address in woDict): woDict[address] = [inst] else: