Ejemplo n.º 1
0
int main()
{
	LLVMContextRef context = LLVMGetGlobalContext();
	LLVMModuleRef module = LLVMModuleCreateWithName("test-101");
	LLVMBuilderRef builder = LLVMCreateBuilder();
	// LLVMInt32Type()
	// LLVMFunctionType(rtnType, paramType, parmCnt, isVarArg)
	// LLVMAddFunction(module, name, functionType)
	LLVMTypeRef main = LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0);
	LLVMValueRef mainFn = LLVMAddFunction(module, "main", main);
	LLVMBasicBlockRef mainBlk = LLVMAppendBasicBlock(mainFn, "entry");
	LLVMPositionBuilderAtEnd(builder, mainBlk);
	LLVMValueRef str =
	    LLVMBuildGlobalStringPtr(builder, "Hello World!", "str");
	LLVMTypeRef args[1];
	args[0] = LLVMPointerType(LLVMInt8Type(), 0);
	LLVMTypeRef puts = LLVMFunctionType(LLVMInt32Type(), args, 1, 0);
	LLVMValueRef putsFn = LLVMAddFunction(module, "puts", puts);

	LLVMBuildCall(builder, putsFn, &str, 1, "");

	LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 0, 0));

	LLVMDumpModule(module);

	return 0;
}
Ejemplo n.º 2
0
void
vm_state_destroy(struct vm_state *vm)
{
   LLVMBasicBlockRef current_block, return_block;
   char *error;

   current_block = LLVMGetInsertBlock(vm->builder);
   return_block = LLVMInsertBasicBlock(current_block, "ret");

   LLVMPositionBuilderAtEnd(vm->builder, current_block);
   LLVMBuildBr(vm->builder, return_block);

   LLVMPositionBuilderAtEnd(vm->builder, return_block);
   LLVMBuildRetVoid(vm->builder);

   LLVMMoveBasicBlockAfter(return_block, current_block);

   LLVMDumpModule(vm->module);

   error = NULL;
   LLVMVerifyModule(vm->module, LLVMAbortProcessAction, &error);
   LLVMDisposeMessage(error);

   LLVMDisposeBuilder(vm->builder);
   LLVMDisposeModule(vm->module);
   symbol_table_destroy(vm->symtab);
}
Ejemplo n.º 3
0
Archivo: hi2.c Proyecto: alexmavr/pzcc
int main (void) {
    LLVMModuleRef module = LLVMModuleCreateWithName("kal");
    LLVMBuilderRef builder = LLVMCreateBuilder();
//	LLVMInitializeNativeTarget();

	LLVMTypeRef funcType = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0);
	LLVMValueRef func = LLVMAddFunction(module, "main", funcType);
	LLVMSetLinkage(func, LLVMExternalLinkage);
	LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
	LLVMPositionBuilderAtEnd(builder, block);

	LLVMValueRef cond = LLVMBuildICmp(builder, LLVMIntNE, LLVMConstInt(LLVMInt32Type(), 2, 0), LLVMConstInt(LLVMInt32Type(), 1, 0), "ifcond");

	LLVMValueRef owning_block = LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder));	//TODO: WRONG??
	//LLVMValueRef owning_block = LLVMBasicBlockAsValue(LLVMGetPreviousBasicBlock(LLVMGetInsertBlock(builder)));
	// 2. Generate new blocks for cases.
	LLVMBasicBlockRef then_ref = LLVMAppendBasicBlock(owning_block, "then");
	LLVMBasicBlockRef else_ref = LLVMAppendBasicBlock(owning_block, "else");
	LLVMBasicBlockRef merge_ref = LLVMAppendBasicBlock(owning_block, "ifmerge");

	// 3. Branch conditionally on then or else.
	LLVMBuildCondBr(builder, cond, then_ref, else_ref);

	// 4. Build then branch prologue.
	LLVMPositionBuilderAtEnd(builder, then_ref);

	LLVMValueRef hi1 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp");

	// 5. Connect then branch to merge block.
	LLVMBuildBr(builder, merge_ref);

	then_ref = LLVMGetInsertBlock(builder);

	// 6. Build else branch prologue.
	LLVMPositionBuilderAtEnd(builder, else_ref);

	LLVMValueRef hi2 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp2");

	// 7. Connect else branch to merge block.
	LLVMBuildBr(builder, merge_ref);

	else_ref = LLVMGetInsertBlock(builder);
	// 8. Position ourselves after the merge block.
	LLVMPositionBuilderAtEnd(builder, merge_ref);
	// 9. Build the phi node.
//	LLVMValueRef phi = LLVMBuildPhi(builder, LLVMDoubleType(), "phi");
	// 10. Add incoming edges.
//	LLVMAddIncoming(phi, &hi1, &then_ref, 1);
//	LLVMAddIncoming(phi, &hi2, &else_ref, 1);

	LLVMDumpModule(module);
	LLVMDisposeBuilder(builder);
	LLVMDisposeModule(module);

	return 0;
}
Ejemplo n.º 4
0
int LLVM_execute(LLVMCompiledProgram program)
{
  LLVMModuleRef module = program.module;
  LLVMValueRef function = program.function;

  char *error = NULL; // Used to retrieve messages from functions

  LLVMExecutionEngineRef engine;
  LLVMModuleProviderRef provider = LLVMCreateModuleProviderForExistingModule(module);
  error = NULL;
  if(LLVMCreateJITCompiler(&engine, provider, 2, &error) != 0) {
    fprintf(stderr, "%s\n", error);
    LLVMDisposeMessage(error);
    abort();
  }

  LLVMPassManagerRef pass = LLVMCreatePassManager();
  LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
  LLVMAddConstantPropagationPass(pass);
  LLVMAddInstructionCombiningPass(pass);
  LLVMAddPromoteMemoryToRegisterPass(pass);
  LLVMAddGVNPass(pass);
  LLVMAddCFGSimplificationPass(pass);
  LLVMRunPassManager(pass, module);
#ifdef NDEBUG
#else
  LLVMDumpModule(module);
#endif

  LLVMGenericValueRef exec_args[] = {};
  LLVMGenericValueRef exec_res = LLVMRunFunction(engine, function, 0, exec_args);

  int result = LLVMGenericValueToInt(exec_res, 0);

  LLVMDisposePassManager(pass);
  LLVMDisposeExecutionEngine(engine);

  return result;
}
Ejemplo n.º 5
0
unsigned r600_llvm_compile(
	LLVMModuleRef mod,
	enum radeon_family family,
	struct r600_bytecode *bc,
	boolean *use_kill,
	unsigned dump,
	struct pipe_debug_callback *debug)
{
	unsigned r;
	struct radeon_shader_binary binary;
	const char * gpu_family = r600_get_llvm_processor_name(family);

	radeon_shader_binary_init(&binary);
	if (dump)
		LLVMDumpModule(mod);
	r = radeon_llvm_compile(mod, &binary, gpu_family, NULL, debug);

	r = r600_create_shader(bc, &binary, use_kill);

	radeon_shader_binary_clean(&binary);

	return r;
}
void
lp_build_tgsi_aos(struct gallivm_state *gallivm,
                  const struct tgsi_token *tokens,
                  struct lp_type type,
                  const unsigned char swizzles[4],
                  LLVMValueRef consts_ptr,
                  const LLVMValueRef *inputs,
                  LLVMValueRef *outputs,
                  struct lp_build_sampler_aos *sampler,
                  const struct tgsi_shader_info *info)
{
   struct lp_build_tgsi_aos_context bld;
   struct tgsi_parse_context parse;
   uint num_immediates = 0;
   unsigned chan;
   int pc = 0;

   /* Setup build context */
   memset(&bld, 0, sizeof bld);
   lp_build_context_init(&bld.bld_base.base, gallivm, type);
   lp_build_context_init(&bld.bld_base.uint_bld, gallivm, lp_uint_type(type));
   lp_build_context_init(&bld.bld_base.int_bld, gallivm, lp_int_type(type));
   lp_build_context_init(&bld.int_bld, gallivm, lp_int_type(type));

   for (chan = 0; chan < 4; ++chan) {
      bld.swizzles[chan] = swizzles[chan];
      bld.inv_swizzles[swizzles[chan]] = chan;
   }

   bld.inputs = inputs;
   bld.outputs = outputs;
   bld.consts_ptr = consts_ptr;
   bld.sampler = sampler;
   bld.indirect_files = info->indirect_files;
   bld.bld_base.emit_swizzle = swizzle_aos;
   bld.bld_base.info = info;

   bld.bld_base.emit_fetch_funcs[TGSI_FILE_CONSTANT] = emit_fetch_constant;
   bld.bld_base.emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
   bld.bld_base.emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
   bld.bld_base.emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;

   /* Set opcode actions */
   lp_set_default_actions_cpu(&bld.bld_base);

   if (!lp_bld_tgsi_list_init(&bld.bld_base)) {
      return;
   }

   tgsi_parse_init(&parse, tokens);

   while (!tgsi_parse_end_of_tokens(&parse)) {
      tgsi_parse_token(&parse);

      switch(parse.FullToken.Token.Type) {
      case TGSI_TOKEN_TYPE_DECLARATION:
         /* Inputs already interpolated */
         lp_emit_declaration_aos(&bld, &parse.FullToken.FullDeclaration);
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         /* save expanded instruction */
         lp_bld_tgsi_add_instruction(&bld.bld_base,
                                     &parse.FullToken.FullInstruction);
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         /* simply copy the immediate values into the next immediates[] slot */
         {
            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
            float imm[4];
            assert(size <= 4);
            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
            for (chan = 0; chan < 4; ++chan) {
               imm[chan] = 0.0f;
            }
            for (chan = 0; chan < size; ++chan) {
               unsigned swizzle = bld.swizzles[chan];
               imm[swizzle] = parse.FullToken.FullImmediate.u[chan].Float;
            }
            bld.immediates[num_immediates] =
                     lp_build_const_aos(gallivm, type,
                                        imm[0], imm[1], imm[2], imm[3],
                                        NULL);
            num_immediates++;
         }
         break;

      case TGSI_TOKEN_TYPE_PROPERTY:
         break;

      default:
         assert(0);
      }
   }

   while (pc != -1) {
      struct tgsi_full_instruction *instr = bld.bld_base.instructions + pc;
      const struct tgsi_opcode_info *opcode_info =
         tgsi_get_opcode_info(instr->Instruction.Opcode);
      if (!lp_emit_instruction_aos(&bld, instr, opcode_info, &pc))
         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
                       opcode_info->mnemonic);
   }

   if (0) {
      LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
      LLVMValueRef function = LLVMGetBasicBlockParent(block);
      debug_printf("11111111111111111111111111111 \n");
      tgsi_dump(tokens, 0);
      lp_debug_dump_value(function);
      debug_printf("2222222222222222222222222222 \n");
   }
   tgsi_parse_free(&parse);
   FREE(bld.bld_base.instructions);

   if (0) {
      LLVMModuleRef module = LLVMGetGlobalParent(
         LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
      LLVMDumpModule(module);
   }

}
Ejemplo n.º 7
0
/**
 * Compile an LLVM module to machine code.
 *
 * @returns 0 for success, 1 for failure
 */
unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binary,
			  const char *gpu_family, unsigned dump, LLVMTargetMachineRef tm)
{

	char cpu[CPU_STRING_LEN];
	char fs[FS_STRING_LEN];
	char *err;
	bool dispose_tm = false;
	LLVMContextRef llvm_ctx;
	unsigned rval = 0;
	LLVMMemoryBufferRef out_buffer;
	unsigned buffer_size;
	const char *buffer_data;
	char triple[TRIPLE_STRING_LEN];
	LLVMBool mem_err;

	if (!tm) {
		strncpy(triple, "r600--", TRIPLE_STRING_LEN);
		LLVMTargetRef target = radeon_llvm_get_r600_target(triple);
		if (!target) {
			return 1;
		}
		strncpy(cpu, gpu_family, CPU_STRING_LEN);
		memset(fs, 0, sizeof(fs));
		if (dump) {
			strncpy(fs, "+DumpCode", FS_STRING_LEN);
		}
		tm = LLVMCreateTargetMachine(target, triple, cpu, fs,
				  LLVMCodeGenLevelDefault, LLVMRelocDefault,
						  LLVMCodeModelDefault);
		dispose_tm = true;
	}
	if (dump) {
		LLVMDumpModule(M);
	}
	/* Setup Diagnostic Handler*/
	llvm_ctx = LLVMGetModuleContext(M);

#if HAVE_LLVM >= 0x0305
	LLVMContextSetDiagnosticHandler(llvm_ctx, radeonDiagnosticHandler, &rval);
#endif
	rval = 0;

	/* Compile IR*/
	mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
								 &out_buffer);

	/* Process Errors/Warnings */
	if (mem_err) {
		fprintf(stderr, "%s: %s", __FUNCTION__, err);
		FREE(err);
		LLVMDisposeTargetMachine(tm);
		return 1;
	}

	if (0 != rval) {
		fprintf(stderr, "%s: Processing Diag Flag\n", __FUNCTION__);
	}

	/* Extract Shader Code*/
	buffer_size = LLVMGetBufferSize(out_buffer);
	buffer_data = LLVMGetBufferStart(out_buffer);

	radeon_elf_read(buffer_data, buffer_size, binary, dump);

	/* Clean up */
	LLVMDisposeMemoryBuffer(out_buffer);

	if (dispose_tm) {
		LLVMDisposeTargetMachine(tm);
	}
	return rval;
}
Ejemplo n.º 8
0
SCM llvm_dump_module(SCM scm_self)
{
  struct llvm_module_t *self = get_llvm(scm_self);
  LLVMDumpModule(self->module);
  return SCM_UNSPECIFIED;
}
Ejemplo n.º 9
0
Archivo: lp_jit.c Proyecto: Gnurou/mesa
static void
lp_jit_create_types(struct lp_fragment_shader_variant *lp)
{
   struct gallivm_state *gallivm = lp->gallivm;
   LLVMContextRef lc = gallivm->context;
   LLVMTypeRef viewport_type, texture_type, sampler_type;

   /* struct lp_jit_viewport */
   {
      LLVMTypeRef elem_types[LP_JIT_VIEWPORT_NUM_FIELDS];

      elem_types[LP_JIT_VIEWPORT_MIN_DEPTH] =
      elem_types[LP_JIT_VIEWPORT_MAX_DEPTH] = LLVMFloatTypeInContext(lc);

      viewport_type = LLVMStructTypeInContext(lc, elem_types,
                                              Elements(elem_types), 0);

      LP_CHECK_MEMBER_OFFSET(struct lp_jit_viewport, min_depth,
                             gallivm->target, viewport_type,
                             LP_JIT_VIEWPORT_MIN_DEPTH);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_viewport, max_depth,
                             gallivm->target, viewport_type,
                             LP_JIT_VIEWPORT_MAX_DEPTH);
      LP_CHECK_STRUCT_SIZE(struct lp_jit_viewport,
                           gallivm->target, viewport_type);
   }

   /* struct lp_jit_texture */
   {
      LLVMTypeRef elem_types[LP_JIT_TEXTURE_NUM_FIELDS];

      elem_types[LP_JIT_TEXTURE_WIDTH]  =
      elem_types[LP_JIT_TEXTURE_HEIGHT] =
      elem_types[LP_JIT_TEXTURE_DEPTH] =
      elem_types[LP_JIT_TEXTURE_FIRST_LEVEL] =
      elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32TypeInContext(lc);
      elem_types[LP_JIT_TEXTURE_BASE] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
      elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
      elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
      elem_types[LP_JIT_TEXTURE_MIP_OFFSETS] =
         LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TEXTURE_LEVELS);

      texture_type = LLVMStructTypeInContext(lc, elem_types,
                                             Elements(elem_types), 0);

      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_WIDTH);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, height,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_HEIGHT);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, depth,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_DEPTH);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, first_level,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_FIRST_LEVEL);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_LAST_LEVEL);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, base,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_BASE);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_ROW_STRIDE);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_IMG_STRIDE);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, mip_offsets,
                             gallivm->target, texture_type,
                             LP_JIT_TEXTURE_MIP_OFFSETS);
      LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
                           gallivm->target, texture_type);
   }

   /* struct lp_jit_sampler */
   {
      LLVMTypeRef elem_types[LP_JIT_SAMPLER_NUM_FIELDS];
      elem_types[LP_JIT_SAMPLER_MIN_LOD] =
      elem_types[LP_JIT_SAMPLER_MAX_LOD] =
      elem_types[LP_JIT_SAMPLER_LOD_BIAS] = LLVMFloatTypeInContext(lc);
      elem_types[LP_JIT_SAMPLER_BORDER_COLOR] =
         LLVMArrayType(LLVMFloatTypeInContext(lc), 4);

      sampler_type = LLVMStructTypeInContext(lc, elem_types,
                                             Elements(elem_types), 0);

      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, min_lod,
                             gallivm->target, sampler_type,
                             LP_JIT_SAMPLER_MIN_LOD);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, max_lod,
                             gallivm->target, sampler_type,
                             LP_JIT_SAMPLER_MAX_LOD);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, lod_bias,
                             gallivm->target, sampler_type,
                             LP_JIT_SAMPLER_LOD_BIAS);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, border_color,
                             gallivm->target, sampler_type,
                             LP_JIT_SAMPLER_BORDER_COLOR);
      LP_CHECK_STRUCT_SIZE(struct lp_jit_sampler,
                           gallivm->target, sampler_type);
   }

   /* struct lp_jit_context */
   {
      LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
      LLVMTypeRef context_type;

      elem_types[LP_JIT_CTX_CONSTANTS] =
         LLVMArrayType(LLVMPointerType(LLVMFloatTypeInContext(lc), 0), LP_MAX_TGSI_CONST_BUFFERS);
      elem_types[LP_JIT_CTX_NUM_CONSTANTS] =
            LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TGSI_CONST_BUFFERS);
      elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc);
      elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] =
      elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32TypeInContext(lc);
      elem_types[LP_JIT_CTX_U8_BLEND_COLOR] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
      elem_types[LP_JIT_CTX_F_BLEND_COLOR] = LLVMPointerType(LLVMFloatTypeInContext(lc), 0);
      elem_types[LP_JIT_CTX_VIEWPORTS] = LLVMPointerType(viewport_type, 0);
      elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type,
                                                      PIPE_MAX_SHADER_SAMPLER_VIEWS);
      elem_types[LP_JIT_CTX_SAMPLERS] = LLVMArrayType(sampler_type,
                                                      PIPE_MAX_SAMPLERS);

      context_type = LLVMStructTypeInContext(lc, elem_types,
                                             Elements(elem_types), 0);

      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants,
                             gallivm->target, context_type,
                             LP_JIT_CTX_CONSTANTS);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, num_constants,
                             gallivm->target, context_type,
                             LP_JIT_CTX_NUM_CONSTANTS);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
                             gallivm->target, context_type,
                             LP_JIT_CTX_ALPHA_REF);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front,
                             gallivm->target, context_type,
                             LP_JIT_CTX_STENCIL_REF_FRONT);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back,
                             gallivm->target, context_type,
                             LP_JIT_CTX_STENCIL_REF_BACK);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, u8_blend_color,
                             gallivm->target, context_type,
                             LP_JIT_CTX_U8_BLEND_COLOR);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, f_blend_color,
                             gallivm->target, context_type,
                             LP_JIT_CTX_F_BLEND_COLOR);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, viewports,
                             gallivm->target, context_type,
                             LP_JIT_CTX_VIEWPORTS);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
                             gallivm->target, context_type,
                             LP_JIT_CTX_TEXTURES);
      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers,
                             gallivm->target, context_type,
                             LP_JIT_CTX_SAMPLERS);
      LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
                           gallivm->target, context_type);

      lp->jit_context_ptr_type = LLVMPointerType(context_type, 0);
   }

   /* struct lp_jit_thread_data */
   {
      LLVMTypeRef elem_types[LP_JIT_THREAD_DATA_COUNT];
      LLVMTypeRef thread_data_type;

      elem_types[LP_JIT_THREAD_DATA_COUNTER] = LLVMInt64TypeInContext(lc);
      elem_types[LP_JIT_THREAD_DATA_RASTER_STATE_VIEWPORT_INDEX] =
            LLVMInt32TypeInContext(lc);

      thread_data_type = LLVMStructTypeInContext(lc, elem_types,
                                                 Elements(elem_types), 0);

      lp->jit_thread_data_ptr_type = LLVMPointerType(thread_data_type, 0);
   }

   if (gallivm_debug & GALLIVM_DEBUG_IR) {
      LLVMDumpModule(gallivm->module);
   }
}
Ejemplo n.º 10
0
ALIGN_STACK
static boolean
test_one(unsigned verbose,
         FILE *fp,
         const struct pipe_blend_state *blend,
         enum vector_mode mode,
         struct lp_type type)
{
   LLVMModuleRef module = NULL;
   LLVMValueRef func = NULL;
   LLVMExecutionEngineRef engine = NULL;
   LLVMModuleProviderRef provider = NULL;
   LLVMPassManagerRef pass = NULL;
   char *error = NULL;
   blend_test_ptr_t blend_test_ptr;
   boolean success;
   const unsigned n = LP_TEST_NUM_SAMPLES;
   int64_t cycles[LP_TEST_NUM_SAMPLES];
   double cycles_avg = 0.0;
   unsigned i, j;

   if(verbose >= 1)
      dump_blend_type(stdout, blend, mode, type);

   module = LLVMModuleCreateWithName("test");

   func = add_blend_test(module, blend, mode, type);

   if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
      LLVMDumpModule(module);
      abort();
   }
   LLVMDisposeMessage(error);

   provider = LLVMCreateModuleProviderForExistingModule(module);
   if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
      if(verbose < 1)
         dump_blend_type(stderr, blend, mode, type);
      fprintf(stderr, "%s\n", error);
      LLVMDisposeMessage(error);
      abort();
   }

#if 0
   pass = LLVMCreatePassManager();
   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
    * but there are more on SVN. */
   LLVMAddConstantPropagationPass(pass);
   LLVMAddInstructionCombiningPass(pass);
   LLVMAddPromoteMemoryToRegisterPass(pass);
   LLVMAddGVNPass(pass);
   LLVMAddCFGSimplificationPass(pass);
   LLVMRunPassManager(pass, module);
#else
   (void)pass;
#endif

   if(verbose >= 2)
      LLVMDumpModule(module);

   blend_test_ptr = (blend_test_ptr_t)LLVMGetPointerToGlobal(engine, func);

   if(verbose >= 2)
      lp_disassemble(blend_test_ptr);

   success = TRUE;
   for(i = 0; i < n && success; ++i) {
      if(mode == AoS) {
         ALIGN16_ATTRIB uint8_t src[LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t dst[LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t con[LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t res[LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t ref[LP_NATIVE_VECTOR_WIDTH/8];
         int64_t start_counter = 0;
         int64_t end_counter = 0;

         random_vec(type, src);
         random_vec(type, dst);
         random_vec(type, con);

         {
            double fsrc[LP_MAX_VECTOR_LENGTH];
            double fdst[LP_MAX_VECTOR_LENGTH];
            double fcon[LP_MAX_VECTOR_LENGTH];
            double fref[LP_MAX_VECTOR_LENGTH];

            read_vec(type, src, fsrc);
            read_vec(type, dst, fdst);
            read_vec(type, con, fcon);

            for(j = 0; j < type.length; j += 4)
               compute_blend_ref(blend, fsrc + j, fdst + j, fcon + j, fref + j);

            write_vec(type, ref, fref);
         }

         start_counter = rdtsc();
         blend_test_ptr(src, dst, con, res);
         end_counter = rdtsc();

         cycles[i] = end_counter - start_counter;

         if(!compare_vec(type, res, ref)) {
            success = FALSE;

            if(verbose < 1)
               dump_blend_type(stderr, blend, mode, type);
            fprintf(stderr, "MISMATCH\n");

            fprintf(stderr, "  Src: ");
            dump_vec(stderr, type, src);
            fprintf(stderr, "\n");

            fprintf(stderr, "  Dst: ");
            dump_vec(stderr, type, dst);
            fprintf(stderr, "\n");

            fprintf(stderr, "  Con: ");
            dump_vec(stderr, type, con);
            fprintf(stderr, "\n");

            fprintf(stderr, "  Res: ");
            dump_vec(stderr, type, res);
            fprintf(stderr, "\n");

            fprintf(stderr, "  Ref: ");
            dump_vec(stderr, type, ref);
            fprintf(stderr, "\n");
         }
      }

      if(mode == SoA) {
         const unsigned stride = type.length*type.width/8;
         ALIGN16_ATTRIB uint8_t src[4*LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t dst[4*LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t con[4*LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t res[4*LP_NATIVE_VECTOR_WIDTH/8];
         ALIGN16_ATTRIB uint8_t ref[4*LP_NATIVE_VECTOR_WIDTH/8];
         int64_t start_counter = 0;
         int64_t end_counter = 0;
         boolean mismatch;

         for(j = 0; j < 4; ++j) {
            random_vec(type, src + j*stride);
            random_vec(type, dst + j*stride);
            random_vec(type, con + j*stride);
         }

         {
            double fsrc[4];
            double fdst[4];
            double fcon[4];
            double fref[4];
            unsigned k;

            for(k = 0; k < type.length; ++k) {
               for(j = 0; j < 4; ++j) {
                  fsrc[j] = read_elem(type, src + j*stride, k);
                  fdst[j] = read_elem(type, dst + j*stride, k);
                  fcon[j] = read_elem(type, con + j*stride, k);
               }

               compute_blend_ref(blend, fsrc, fdst, fcon, fref);

               for(j = 0; j < 4; ++j)
                  write_elem(type, ref + j*stride, k, fref[j]);
            }
         }

         start_counter = rdtsc();
         blend_test_ptr(src, dst, con, res);
         end_counter = rdtsc();

         cycles[i] = end_counter - start_counter;

         mismatch = FALSE;
         for (j = 0; j < 4; ++j)
            if(!compare_vec(type, res + j*stride, ref + j*stride))
               mismatch = TRUE;

         if (mismatch) {
            success = FALSE;

            if(verbose < 1)
               dump_blend_type(stderr, blend, mode, type);
            fprintf(stderr, "MISMATCH\n");
            for(j = 0; j < 4; ++j) {
               char channel = "RGBA"[j];
               fprintf(stderr, "  Src%c: ", channel);
               dump_vec(stderr, type, src + j*stride);
               fprintf(stderr, "\n");

               fprintf(stderr, "  Dst%c: ", channel);
               dump_vec(stderr, type, dst + j*stride);
               fprintf(stderr, "\n");

               fprintf(stderr, "  Con%c: ", channel);
               dump_vec(stderr, type, con + j*stride);
               fprintf(stderr, "\n");

               fprintf(stderr, "  Res%c: ", channel);
               dump_vec(stderr, type, res + j*stride);
               fprintf(stderr, "\n");

               fprintf(stderr, "  Ref%c: ", channel);
               dump_vec(stderr, type, ref + j*stride);
               fprintf(stderr, "\n");
            }
         }
      }
   }

   /*
    * Unfortunately the output of cycle counter is not very reliable as it comes
    * -- sometimes we get outliers (due IRQs perhaps?) which are
    * better removed to avoid random or biased data.
    */
   {
      double sum = 0.0, sum2 = 0.0;
      double avg, std;
      unsigned m;

      for(i = 0; i < n; ++i) {
         sum += cycles[i];
         sum2 += cycles[i]*cycles[i];
      }

      avg = sum/n;
      std = sqrtf((sum2 - n*avg*avg)/n);

      m = 0;
      sum = 0.0;
      for(i = 0; i < n; ++i) {
         if(fabs(cycles[i] - avg) <= 4.0*std) {
            sum += cycles[i];
            ++m;
         }
      }

      cycles_avg = sum/m;

   }

   if(fp)
      write_tsv_row(fp, blend, mode, type, cycles_avg, success);

   if (!success) {
      if(verbose < 2)
         LLVMDumpModule(module);
      LLVMWriteBitcodeToFile(module, "blend.bc");
      fprintf(stderr, "blend.bc written\n");
      fprintf(stderr, "Invoke as \"llc -o - blend.bc\"\n");
      abort();
   }

   LLVMFreeMachineCodeForFunction(engine, func);

   LLVMDisposeExecutionEngine(engine);
   if(pass)
      LLVMDisposePassManager(pass);

   return success;
}
Ejemplo n.º 11
0
PIPE_ALIGN_STACK
static boolean
test_round(unsigned verbose, FILE *fp)
{
   LLVMModuleRef module = NULL;
   LLVMValueRef test_round = NULL, test_trunc, test_floor, test_ceil;
   LLVMExecutionEngineRef engine = lp_build_engine;
   LLVMPassManagerRef pass = NULL;
   char *error = NULL;
   test_round_t round_func, trunc_func, floor_func, ceil_func;
   float unpacked[4];
   unsigned packed;
   boolean success = TRUE;
   int i;

   module = LLVMModuleCreateWithName("test");

   test_round = add_test(module, "round", lp_build_round);
   test_trunc = add_test(module, "trunc", lp_build_trunc);
   test_floor = add_test(module, "floor", lp_build_floor);
   test_ceil = add_test(module, "ceil", lp_build_ceil);

   if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
      printf("LLVMVerifyModule: %s\n", error);
      LLVMDumpModule(module);
      abort();
   }
   LLVMDisposeMessage(error);

#if 0
   pass = LLVMCreatePassManager();
   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
    * but there are more on SVN. */
   LLVMAddConstantPropagationPass(pass);
   LLVMAddInstructionCombiningPass(pass);
   LLVMAddPromoteMemoryToRegisterPass(pass);
   LLVMAddGVNPass(pass);
   LLVMAddCFGSimplificationPass(pass);
   LLVMRunPassManager(pass, module);
#else
   (void)pass;
#endif

   round_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_round));
   trunc_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_trunc));
   floor_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_floor));
   ceil_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_ceil));

   memset(unpacked, 0, sizeof unpacked);
   packed = 0;

   if (0)
      LLVMDumpModule(module);

   for (i = 0; i < 3; i++) {
      v4sf xvals[3] = {
         {-10.0, -1, 0, 12.0},
         {-1.5, -0.25, 1.25, 2.5},
         {-0.99, -0.01, 0.01, 0.99}
      };
      v4sf x = xvals[i];
      v4sf y, ref;
      float *xp = (float *) &x;
      float *refp = (float *) &ref;

      printf("\n");
      printv("x            ", x);

      refp[0] = round(xp[0]);
      refp[1] = round(xp[1]);
      refp[2] = round(xp[2]);
      refp[3] = round(xp[3]);
      y = round_func(x);
      printv("C round(x)   ", ref);
      printv("LLVM round(x)", y);
      compare(ref, y);

      refp[0] = trunc(xp[0]);
      refp[1] = trunc(xp[1]);
      refp[2] = trunc(xp[2]);
      refp[3] = trunc(xp[3]);
      y = trunc_func(x);
      printv("C trunc(x)   ", ref);
      printv("LLVM trunc(x)", y);
      compare(ref, y);

      refp[0] = floor(xp[0]);
      refp[1] = floor(xp[1]);
      refp[2] = floor(xp[2]);
      refp[3] = floor(xp[3]);
      y = floor_func(x);
      printv("C floor(x)   ", ref);
      printv("LLVM floor(x)", y);
      compare(ref, y);

      refp[0] = ceil(xp[0]);
      refp[1] = ceil(xp[1]);
      refp[2] = ceil(xp[2]);
      refp[3] = ceil(xp[3]);
      y = ceil_func(x);
      printv("C ceil(x)    ", ref);
      printv("LLVM ceil(x) ", y);
      compare(ref, y);
   }

   LLVMFreeMachineCodeForFunction(engine, test_round);
   LLVMFreeMachineCodeForFunction(engine, test_trunc);
   LLVMFreeMachineCodeForFunction(engine, test_floor);
   LLVMFreeMachineCodeForFunction(engine, test_ceil);

   LLVMDisposeExecutionEngine(engine);
   if(pass)
      LLVMDisposePassManager(pass);

   return success;
}
Ejemplo n.º 12
0
/**
 * Compile an LLVM module to machine code.
 *
 * @returns 0 for success, 1 for failure
 */
unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_llvm_binary *binary,
					  const char * gpu_family, unsigned dump) {

	LLVMTargetRef target;
	LLVMTargetMachineRef tm;
	char cpu[CPU_STRING_LEN];
	char fs[FS_STRING_LEN];
	char *err;
	LLVMMemoryBufferRef out_buffer;
	unsigned buffer_size;
	const char *buffer_data;
	char triple[TRIPLE_STRING_LEN];
	char *elf_buffer;
	Elf *elf;
	Elf_Scn *section = NULL;
	size_t section_str_index;
	LLVMBool r;

	init_r600_target();

	target = get_r600_target();
	if (!target) {
		return 1;
	}

	strncpy(cpu, gpu_family, CPU_STRING_LEN);
	memset(fs, 0, sizeof(fs));
	if (dump) {
		LLVMDumpModule(M);
		strncpy(fs, "+DumpCode", FS_STRING_LEN);
	}
	strncpy(triple, "r600--", TRIPLE_STRING_LEN);
	tm = LLVMCreateTargetMachine(target, triple, cpu, fs,
				  LLVMCodeGenLevelDefault, LLVMRelocDefault,
						  LLVMCodeModelDefault);

	r = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
								 &out_buffer);
	if (r) {
		fprintf(stderr, "%s", err);
		FREE(err);
		return 1;
	}

	buffer_size = LLVMGetBufferSize(out_buffer);
	buffer_data = LLVMGetBufferStart(out_buffer);

	/* One of the libelf implementations
	 * (http://www.mr511.de/software/english.htm) requires calling
	 * elf_version() before elf_memory().
	 */
	elf_version(EV_CURRENT);
	elf_buffer = MALLOC(buffer_size);
	memcpy(elf_buffer, buffer_data, buffer_size);

	elf = elf_memory(elf_buffer, buffer_size);

	elf_getshdrstrndx(elf, &section_str_index);
	binary->disassembled = 0;

	while ((section = elf_nextscn(elf, section))) {
		const char *name;
		Elf_Data *section_data = NULL;
		GElf_Shdr section_header;
		if (gelf_getshdr(section, &section_header) != &section_header) {
			fprintf(stderr, "Failed to read ELF section header\n");
			return 1;
		}
		name = elf_strptr(elf, section_str_index, section_header.sh_name);
		if (!strcmp(name, ".text")) {
			section_data = elf_getdata(section, section_data);
			binary->code_size = section_data->d_size;
			binary->code = MALLOC(binary->code_size * sizeof(unsigned char));
			memcpy(binary->code, section_data->d_buf, binary->code_size);
		} else if (!strcmp(name, ".AMDGPU.config")) {
			section_data = elf_getdata(section, section_data);
			binary->config_size = section_data->d_size;
			binary->config = MALLOC(binary->config_size * sizeof(unsigned char));
			memcpy(binary->config, section_data->d_buf, binary->config_size);
		} else if (dump && !strcmp(name, ".AMDGPU.disasm")) {
			binary->disassembled = 1;
			section_data = elf_getdata(section, section_data);
			fprintf(stderr, "\nShader Disassembly:\n\n");
			fprintf(stderr, "%.*s\n", (int)section_data->d_size,
						  (char *)section_data->d_buf);
		}
	}

	LLVMDisposeMemoryBuffer(out_buffer);
	LLVMDisposeTargetMachine(tm);
	return 0;
}
Ejemplo n.º 13
0
int main(int c, char **v)
{
    LLVMContextRef *contexts;
    LLVMModuleRef *modules;
    char *error;
    const char *mode = "opt";
    const char **filenames;
    unsigned numFiles;
    unsigned i;
    bool moreOptions;
    static int verboseFlag = 0;
    static int timingFlag = 0;
    static int disassembleFlag = 0;
    bool manyContexts = true;
    double beforeAll;
    
    if (c == 1)
        usage();
    
    moreOptions = true;
    while (moreOptions) {
        static struct option longOptions[] = {
            {"verbose", no_argument, &verboseFlag, 1},
            {"timing", no_argument, &timingFlag, 1},
            {"disassemble", no_argument, &disassembleFlag, 1},
            {"mode", required_argument, 0, 0},
            {"contexts", required_argument, 0, 0},
            {"help", no_argument, 0, 0}
        };
        
        int optionIndex;
        int optionValue;
        
        optionValue = getopt_long(c, v, "", longOptions, &optionIndex);
        
        switch (optionValue) {
        case -1:
            moreOptions = false;
            break;
            
        case 0: {
            const char* thisOption = longOptions[optionIndex].name;
            if (!strcmp(thisOption, "help"))
                usage();
            if (!strcmp(thisOption, "contexts")) {
                if (!strcasecmp(optarg, "one"))
                    manyContexts = false;
                else if (!strcasecmp(optarg, "many"))
                    manyContexts = true;
                else {
                    fprintf(stderr, "Invalid argument for --contexts.\n");
                    exit(1);
                }
                break;
            }
            if (!strcmp(thisOption, "mode")) {
                mode = strdup(optarg);
                break;
            }
            break;
        }
            
        case '?':
            exit(0);
            break;
            
        default:
            printf("optionValue = %d\n", optionValue);
            abort();
            break;
        }
    }
    
    LLVMLinkInMCJIT();
    LLVMInitializeNativeTarget();
    LLVMInitializeX86AsmPrinter();
    LLVMInitializeX86Disassembler();

    filenames = (const char **)(v + optind);
    numFiles = c - optind;
    
    contexts = malloc(sizeof(LLVMContextRef) * numFiles);
    modules = malloc(sizeof(LLVMModuleRef) * numFiles);
    
    if (manyContexts) {
        for (i = 0; i < numFiles; ++i)
            contexts[i] = LLVMContextCreate();
    } else {
        LLVMContextRef context = LLVMContextCreate();
        for (i = 0; i < numFiles; ++i)
            contexts[i] = context;
    }
    
    for (i = 0; i < numFiles; ++i) {
        LLVMMemoryBufferRef buffer;
        const char* filename = filenames[i];
        
        if (LLVMCreateMemoryBufferWithContentsOfFile(filename, &buffer, &error)) {
            fprintf(stderr, "Error reading file %s: %s\n", filename, error);
            exit(1);
        }
        
        if (LLVMParseBitcodeInContext(contexts[i], buffer, modules + i, &error)) {
            fprintf(stderr, "Error parsing file %s: %s\n", filename, error);
            exit(1);
        }
        
        LLVMDisposeMemoryBuffer(buffer);
        
        if (verboseFlag) {
            printf("Module #%u (%s) after parsing:\n", i, filename);
            LLVMDumpModule(modules[i]);
        }
    }

    if (verboseFlag)
        printf("Generating code for modules...\n");
    
    if (timingFlag)
        beforeAll = currentTime();
    for (i = 0; i < numFiles; ++i) {
        LLVMModuleRef module;
        LLVMExecutionEngineRef engine;
        struct LLVMMCJITCompilerOptions options;
        LLVMValueRef value;
        LLVMPassManagerRef functionPasses = 0;
        LLVMPassManagerRef modulePasses = 0;
        
        double before;
        
        if (timingFlag)
            before = currentTime();
        
        module = modules[i];

        LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
        options.OptLevel = 2;
        options.EnableFastISel = 0;
        options.MCJMM = LLVMCreateSimpleMCJITMemoryManager(
            0, mmAllocateCodeSection, mmAllocateDataSection, mmApplyPermissions, mmDestroy);
    
        if (LLVMCreateMCJITCompilerForModule(&engine, module, &options, sizeof(options), &error)) {
            fprintf(stderr, "Error building MCJIT: %s\n", error);
            exit(1);
        }
    
        if (!strcasecmp(mode, "simple")) {
            modulePasses = LLVMCreatePassManager();
            LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), modulePasses);
            LLVMAddConstantPropagationPass(modulePasses);
            LLVMAddInstructionCombiningPass(modulePasses);
            LLVMAddPromoteMemoryToRegisterPass(modulePasses);
            LLVMAddBasicAliasAnalysisPass(modulePasses);
            LLVMAddTypeBasedAliasAnalysisPass(modulePasses);
            LLVMAddGVNPass(modulePasses);
            LLVMAddCFGSimplificationPass(modulePasses);
            LLVMRunPassManager(modulePasses, module);
        } else if (!strcasecmp(mode, "opt")) {
            LLVMPassManagerBuilderRef passBuilder;

            passBuilder = LLVMPassManagerBuilderCreate();
            LLVMPassManagerBuilderSetOptLevel(passBuilder, 2);
            LLVMPassManagerBuilderSetSizeLevel(passBuilder, 0);
        
            functionPasses = LLVMCreateFunctionPassManagerForModule(module);
            modulePasses = LLVMCreatePassManager();
        
            LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), modulePasses);
        
            LLVMPassManagerBuilderPopulateFunctionPassManager(passBuilder, functionPasses);
            LLVMPassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses);
        
            LLVMPassManagerBuilderDispose(passBuilder);
        
            LLVMInitializeFunctionPassManager(functionPasses);
            for (value = LLVMGetFirstFunction(module); value; value = LLVMGetNextFunction(value))
                LLVMRunFunctionPassManager(functionPasses, value);
            LLVMFinalizeFunctionPassManager(functionPasses);
        
            LLVMRunPassManager(modulePasses, module);
        } else {
            fprintf(stderr, "Bad optimization mode: %s.\n", mode);
            fprintf(stderr, "Valid modes are: \"simple\" or \"opt\".\n");
            exit(1);
        }

        if (verboseFlag) {
            printf("Module #%d (%s) after optimization:\n", i, filenames[i]);
            LLVMDumpModule(module);
        }
    
        for (value = LLVMGetFirstFunction(module); value; value = LLVMGetNextFunction(value)) {
            if (LLVMIsDeclaration(value))
                continue;
            LLVMGetPointerToGlobal(engine, value);
        }

        if (functionPasses)
            LLVMDisposePassManager(functionPasses);
        if (modulePasses)
            LLVMDisposePassManager(modulePasses);
    
        LLVMDisposeExecutionEngine(engine);
        
        if (timingFlag) {
            double after = currentTime();
            printf("Module #%d (%s) took %lf ms.\n", i, filenames[i], (after - before) * 1000);
        }
    }
    if (timingFlag) {
        double after = currentTime();
        printf("Compilation took a total of %lf ms.\n", (after - beforeAll) * 1000);
    }
    
    if (disassembleFlag) {
        LLVMDisasmContextRef disassembler;
        struct MemorySection *section;
        
        disassembler = LLVMCreateDisasm("x86_64-apple-darwin", 0, 0, 0, symbolLookupCallback);
        if (!disassembler) {
            fprintf(stderr, "Error building disassembler.\n");
            exit(1);
        }
    
        for (section = sectionHead; section; section = section->next) {
            printf("Disassembly for section %p:\n", section);
        
            char pcString[20];
            char instructionString[1000];
            uint8_t *pc;
            uint8_t *end;
        
            pc = section->start;
            end = pc + section->size;
        
            while (pc < end) {
                snprintf(
                    pcString, sizeof(pcString), "0x%lx",
                    (unsigned long)(uintptr_t)pc);
            
                size_t instructionSize = LLVMDisasmInstruction(
                    disassembler, pc, end - pc, (uintptr_t)pc,
                    instructionString, sizeof(instructionString));
            
                if (!instructionSize)
                    snprintf(instructionString, sizeof(instructionString), ".byte 0x%02x", *pc++);
                else
                    pc += instructionSize;
            
                printf("    %16s: %s\n", pcString, instructionString);
            }
        }
    }
    
    return 0;
}
Ejemplo n.º 14
0
int main(int argc, char** argv) {
	llvm::llvm_shutdown_obj Y;
	llvm::error_code ec;
	std::string se;
	std::string file;

	if (argc < 2) {
		llvm::errs() << "Usage llvm-disasm <file>\n";
		return 1;
	}

	llvm::InitializeAllTargetInfos();
	llvm::InitializeAllTargetMCs();
	llvm::InitializeAllAsmParsers();
	llvm::InitializeAllDisassemblers();

	file = argv[1];

	llvm::OwningPtr<llvm::object::Binary> bin;
	ec = llvm::object::createBinary(file, bin);
	if (ec) {
		llvm::errs() << file << ": " << ec.message() << "\n";
		return 1;
	}

	if (!bin->isELF()) {
		llvm::errs() << file << " isn't an object file\n";
		return 1;
	}

	llvm::object::ObjectFile* obj = llvm::dyn_cast<llvm::object::ObjectFile>(bin.get());
	if (!obj) {
		llvm::errs() << file << ": failed to cast to llvm::ObjectFile\n";
		return 1;
	}

	llvm::Triple tri;
	tri.setArch(llvm::Triple::ArchType(obj->getArch()));
	std::string targetName = tri.str();
	const llvm::Target* target = llvm::TargetRegistry::lookupTarget(targetName, se);
	if (!target) {
		llvm::errs() << file << ": failed to get the target descriptor for " << targetName << "\n";
		return 1;
	}

	STI = target->createMCSubtargetInfo(targetName, "", "");
	if (!STI) {
		llvm::errs() << file << ": " << ": to get the subtarget info!\n";
		return 1;
	}

	disasm = target->createMCDisassembler(*STI);
	if (!disasm) {
		llvm::errs() << file << ": " << ": to get the disassembler!\n";
		return 1;
	}

	MII = target->createMCInstrInfo();
    if (!MII) {
		llvm::errs() << file << ": no instruction info for target\n";
		return 1;
    }

	MRI = target->createMCRegInfo(targetName);
    if (!MRI) {
		llvm::errs() << file << ": no register info for target\n";
		return 1;
    }


	llvmBuilder = LLVMCreateBuilder();

	LLVMModuleRef llvmModule = LLVMModuleCreateWithName("test");
	LLVMTypeRef mainType = LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0);
	LLVMValueRef mainFn = LLVMAddFunction(llvmModule, "main", mainType);
	LLVMBasicBlockRef blk = LLVMAppendBasicBlock(mainFn, "");
	LLVMPositionBuilderAtEnd(llvmBuilder, blk);

	for (llvm::object::section_iterator i = obj->begin_sections(), e = obj->end_sections();
		 i != e; 
		 i.increment(ec)) {

		if (ec) {
			llvm::errs() << "Failed to increment the section iterator!\n";
			return 1;
		}

		bool isText;
		llvm::StringRef secName;

		if (i->getName(secName)) {
			llvm::errs() << file << ": failed to get the section name\n";
			break;
		}

		if (i->isText(isText)) {
			llvm::errs() << file << ": " << secName << ": failed to determine the section type\n";
			break;
		}

		if (!isText) {
			continue;
		}

	
		std::set<llvm::object::SymbolRef> symbols;

		for (llvm::object::symbol_iterator isym = obj->begin_symbols();
										   isym != obj->end_symbols();
										   isym.increment(ec)) {
			bool res;
			llvm::StringRef symName;
			llvm::object::SymbolRef::Type symType;

			if (ec) {
				llvm::errs() << "Failed to increment the symbol iterator!\n";
				return 1;		
			}

			if (isym->getName(symName)) {
				llvm::errs() << file << ": " << secName << ": failed to get the symbol name!\n";
				return 1;
			}

			/*
			uint64_t secSize, secBase, symAddr;

			i->getAddress(secBase);
			i->getSize(secSize);
			isym->getAddress(symAddr);

			
			if (i->containsSymbol(*isym, res)) {
				llvm::errs() << file << ": " << secName << ": " << symName << ": failed to check whether the symbol is in the section!\n";
				return 1;
			}

			if (!res) {
				continue;
			}
			
			if (symAddr < secBase || symAddr >= secBase + secSize) {
				continue;
			}
			*/

			llvm::object::section_iterator i2 = llvm::object::section_iterator(llvm::object::SectionRef());
			isym->getSection(i2);
			if (i2 != i) {
				continue;
			}

			if (isym->getType(symType)) {
				llvm::errs() << file << ": " << secName << ": " << symName << ": failed to get the symbol type!\n";
				return 1;
			}

			if (symType != llvm::object::SymbolRef::ST_Function) {
				continue;
			}

			symbols.insert(*isym);
		}

		for (std::set<llvm::object::SymbolRef>::const_iterator	isym = symbols.begin();
																isym != symbols.end();
																++isym) {
			if (analyzeSymbol(*isym)) {
				return 1;
			}
		}
	}

	LLVMDumpModule(llvmModule);

	LLVMDisposeModule(llvmModule);
	LLVMDisposeBuilder(llvmBuilder);

	return 0;
}
Ejemplo n.º 15
0
PIPE_ALIGN_STACK
static boolean
test_one(unsigned verbose,
         FILE *fp,
         struct lp_type src_type,
         struct lp_type dst_type)
{
   LLVMModuleRef module = NULL;
   LLVMValueRef func = NULL;
   LLVMExecutionEngineRef engine = NULL;
   LLVMModuleProviderRef provider = NULL;
   LLVMPassManagerRef pass = NULL;
   char *error = NULL;
   conv_test_ptr_t conv_test_ptr;
   boolean success;
   const unsigned n = LP_TEST_NUM_SAMPLES;
   int64_t cycles[LP_TEST_NUM_SAMPLES];
   double cycles_avg = 0.0;
   unsigned num_srcs;
   unsigned num_dsts;
   double eps;
   unsigned i, j;

   if(verbose >= 1)
      dump_conv_types(stdout, src_type, dst_type);

   if(src_type.length > dst_type.length) {
      num_srcs = 1;
      num_dsts = src_type.length/dst_type.length;
   }
   else  {
      num_dsts = 1;
      num_srcs = dst_type.length/src_type.length;
   }

   assert(src_type.width * src_type.length == dst_type.width * dst_type.length);

   /* We must not loose or gain channels. Only precision */
   assert(src_type.length * num_srcs == dst_type.length * num_dsts);

   eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type));

   module = LLVMModuleCreateWithName("test");

   func = add_conv_test(module, src_type, num_srcs, dst_type, num_dsts);

   if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
      LLVMDumpModule(module);
      abort();
   }
   LLVMDisposeMessage(error);

   provider = LLVMCreateModuleProviderForExistingModule(module);
   if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
      if(verbose < 1)
         dump_conv_types(stderr, src_type, dst_type);
      fprintf(stderr, "%s\n", error);
      LLVMDisposeMessage(error);
      abort();
   }

#if 0
   pass = LLVMCreatePassManager();
   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
    * but there are more on SVN. */
   LLVMAddConstantPropagationPass(pass);
   LLVMAddInstructionCombiningPass(pass);
   LLVMAddPromoteMemoryToRegisterPass(pass);
   LLVMAddGVNPass(pass);
   LLVMAddCFGSimplificationPass(pass);
   LLVMRunPassManager(pass, module);
#else
   (void)pass;
#endif

   if(verbose >= 2)
      LLVMDumpModule(module);

   conv_test_ptr = (conv_test_ptr_t)LLVMGetPointerToGlobal(engine, func);

   if(verbose >= 2)
      lp_disassemble(conv_test_ptr);

   success = TRUE;
   for(i = 0; i < n && success; ++i) {
      unsigned src_stride = src_type.length*src_type.width/8;
      unsigned dst_stride = dst_type.length*dst_type.width/8;
      PIPE_ALIGN_VAR(16) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
      PIPE_ALIGN_VAR(16) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
      double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
      uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
      int64_t start_counter = 0;
      int64_t end_counter = 0;

      for(j = 0; j < num_srcs; ++j) {
         random_vec(src_type, src + j*src_stride);
         read_vec(src_type, src + j*src_stride, fref + j*src_type.length);
      }

      for(j = 0; j < num_dsts; ++j) {
         write_vec(dst_type, ref + j*dst_stride, fref + j*dst_type.length);
      }

      start_counter = rdtsc();
      conv_test_ptr(src, dst);
      end_counter = rdtsc();

      cycles[i] = end_counter - start_counter;

      for(j = 0; j < num_dsts; ++j) {
         if(!compare_vec_with_eps(dst_type, dst + j*dst_stride, ref + j*dst_stride, eps))
            success = FALSE;
      }

      if (!success) {
         if(verbose < 1)
            dump_conv_types(stderr, src_type, dst_type);
         fprintf(stderr, "MISMATCH\n");

         for(j = 0; j < num_srcs; ++j) {
            fprintf(stderr, "  Src%u: ", j);
            dump_vec(stderr, src_type, src + j*src_stride);
            fprintf(stderr, "\n");
         }

#if 1
         fprintf(stderr, "  Ref: ");
         for(j = 0; j < src_type.length*num_srcs; ++j)
            fprintf(stderr, " %f", fref[j]);
         fprintf(stderr, "\n");
#endif

         for(j = 0; j < num_dsts; ++j) {
            fprintf(stderr, "  Dst%u: ", j);
            dump_vec(stderr, dst_type, dst + j*dst_stride);
            fprintf(stderr, "\n");

            fprintf(stderr, "  Ref%u: ", j);
            dump_vec(stderr, dst_type, ref + j*dst_stride);
            fprintf(stderr, "\n");
         }
      }
   }

   /*
    * Unfortunately the output of cycle counter is not very reliable as it comes
    * -- sometimes we get outliers (due IRQs perhaps?) which are
    * better removed to avoid random or biased data.
    */
   {
      double sum = 0.0, sum2 = 0.0;
      double avg, std;
      unsigned m;

      for(i = 0; i < n; ++i) {
         sum += cycles[i];
         sum2 += cycles[i]*cycles[i];
      }

      avg = sum/n;
      std = sqrtf((sum2 - n*avg*avg)/n);

      m = 0;
      sum = 0.0;
      for(i = 0; i < n; ++i) {
         if(fabs(cycles[i] - avg) <= 4.0*std) {
            sum += cycles[i];
            ++m;
         }
      }

      cycles_avg = sum/m;

   }

   if(fp)
      write_tsv_row(fp, src_type, dst_type, cycles_avg, success);

   if (!success) {
      static boolean firsttime = TRUE;
      if(firsttime) {
         if(verbose < 2)
            LLVMDumpModule(module);
         LLVMWriteBitcodeToFile(module, "conv.bc");
         fprintf(stderr, "conv.bc written\n");
         fprintf(stderr, "Invoke as \"llc -o - conv.bc\"\n");
         firsttime = FALSE;
         /* abort(); */
      }
   }

   LLVMFreeMachineCodeForFunction(engine, func);

   LLVMDisposeExecutionEngine(engine);
   if(pass)
      LLVMDisposePassManager(pass);

   return success;
}