示例#1
0
func checkInstr(instr ssa.Instruction, blockDomTree *analysis.DominatorTree) error {
	thisBlockNode := blockDomTree.NodeForBlock(instr.Block())

	if _, ok := instr.(*ssa.Phi); !ok {
		for _, op := range ssa.GetOperands(instr) {
			if opInstr, ok := op.(ssa.Instruction); ok {
				opInstrBlock := opInstr.Block()
				if thisBlockNode.DominatedBy(blockDomTree.NodeForBlock(opInstrBlock), true) {
					continue
				} else if opInstrBlock == instr.Block() {
					if opInstrBlock.InstrIndex(opInstr) < opInstrBlock.InstrIndex(instr) {
						continue
					}
				}

				return &InstrError{
					Instr:   instr,
					Message: "Instruction is not dominated by operand `" + ssa.ValueString(op) + "`",
				}
			}
		}
	}

	switch i := instr.(type) {
	case *ssa.BinOp:
		return checkBinOp(i)
	case *ssa.Load:
		return checkLoad(i)
	case *ssa.Call:
		return checkCall(i)
	case *ssa.Alloc:
		return checkAlloc(i)
	case *ssa.Store:
		return checkStore(i)
	case *ssa.Convert:
		return checkConvert(i)
	case *ssa.ICmp:
		return checkICmp(i)
	case *ssa.CondBr:
		return checkCondBr(i)
	case *ssa.Br:
		return checkBr(i)
	case *ssa.Phi:
		return checkPhi(i, blockDomTree)
	case *ssa.Ret:
		return checkRet(i)
	case *ssa.GEP:
		return checkGEP(i)
	case *ssa.Unreachable:
		// do nothing
	default:
		panic("unim")
	}

	return nil
}
示例#2
0
func PrintValues(mod *ssa.Module, out io.Writer) {
	printf := func(val string, stuff ...interface{}) {
		fmt.Fprintf(out, val, stuff...)
	}

	printf("Values in module `%s`\n", mod.Name())
	printf("\n")

	printf("Globals:\n")
	for _, glob := range mod.Globals() {
		printf("  %s (references: %d)\n", ssa.ValueString(glob), len(glob.References()))
	}
	printf("\n")

	printf("Functions:\n")
	for _, fn := range mod.Functions() {
		printf("  %s (references: %d)\n", ssa.ValueString(fn), len(fn.References()))
		if fn.IsPrototype() {
			printf("\n")
			continue
		}

		printf("    Parameters:\n")

		for _, par := range fn.Parameters() {
			printf("      %s (references: %d)\n", ssa.ValueString(par), len(par.References()))
		}

		printf("    Instruction values:\n")

		for _, block := range fn.Blocks() {
			for _, instr := range block.Instrs() {
				if val, ok := instr.(ssa.Value); ok {
					printf("      %s (references: %d)\n", ssa.ValueString(val), len(val.References()))
				}
			}
		}

		printf("\n")
	}
}