示例#1
0
// parseBasicBlock converts the provided LLVM IR basic block into a basic block
// in which the instructions have been translated to Go AST statement nodes but
// the terminator instruction is an unmodified LLVM IR value.
func parseBasicBlock(llBB llvm.BasicBlock) (bb *basicBlock, err error) {
	name, err := getBBName(llBB.AsValue())
	if err != nil {
		return nil, err
	}
	bb = &basicBlock{name: name, phis: make(map[string][]*definition)}
	for inst := llBB.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) {
		// Handle terminator instruction.
		if inst == llBB.LastInstruction() {
			err = bb.addTerm(inst)
			if err != nil {
				return nil, errutil.Err(err)
			}
			return bb, nil
		}

		// Handle PHI instructions.
		if inst.InstructionOpcode() == llvm.PHI {
			ident, def, err := parsePHIInst(inst)
			if err != nil {
				return nil, errutil.Err(err)
			}
			bb.phis[ident] = def
			continue
		}

		// Handle non-terminator instructions.
		stmt, err := parseInst(inst)
		if err != nil {
			return nil, err
		}
		bb.stmts = append(bb.stmts, stmt)
	}
	return nil, errutil.Newf("invalid basic block %q; contains no instructions", name)
}