Esempio n. 1
0
int llvm_test_callsite_attributes(void) {
  LLVMEnablePrettyStackTrace();

  LLVMModuleRef M = llvm_load_module(false, true);

  LLVMValueRef F = LLVMGetFirstFunction(M);
  while (F) {
    LLVMBasicBlockRef BB;
    for (BB = LLVMGetFirstBasicBlock(F); BB; BB = LLVMGetNextBasicBlock(BB)) {
      LLVMValueRef I;
      for (I = LLVMGetFirstInstruction(BB); I; I = LLVMGetNextInstruction(I)) {
        if (LLVMIsACallInst(I)) {
          // Read attributes
          int Idx, ParamCount;
          for (Idx = LLVMAttributeFunctionIndex,
              ParamCount = LLVMCountParams(F);
               Idx <= ParamCount; ++Idx) {
            int AttrCount = LLVMGetCallSiteAttributeCount(I, Idx);
            LLVMAttributeRef *Attrs = (LLVMAttributeRef *)malloc(
                AttrCount * sizeof(LLVMAttributeRef));
            assert(Attrs);
            LLVMGetCallSiteAttributes(I, Idx, Attrs);
            free(Attrs);
          }
        }
      }
    }

    F = LLVMGetNextFunction(F);
  }

  LLVMDisposeModule(M);

  return 0;
}
Esempio n. 2
0
int llvm_test_function_attributes(void) {
  LLVMEnablePrettyStackTrace();

  LLVMModuleRef M = llvm_load_module(false, true);

  LLVMValueRef F = LLVMGetFirstFunction(M);
  while (F) {
    // Read attributes
    int Idx, ParamCount;
    for (Idx = LLVMAttributeFunctionIndex, ParamCount = LLVMCountParams(F);
         Idx <= ParamCount; ++Idx) {
      int AttrCount = LLVMGetAttributeCountAtIndex(F, Idx);
      LLVMAttributeRef *Attrs =
          (LLVMAttributeRef *)malloc(AttrCount * sizeof(LLVMAttributeRef));
      assert(Attrs);
      LLVMGetAttributesAtIndex(F, Idx, Attrs);
      free(Attrs);
    }
    F = LLVMGetNextFunction(F);
  }

  LLVMDisposeModule(M);

  return 0;
}
Esempio n. 3
0
static void radeon_llvm_optimize(LLVMModuleRef mod)
{
	const char *data_layout = LLVMGetDataLayout(mod);
	LLVMTargetDataRef TD = LLVMCreateTargetData(data_layout);
	LLVMPassManagerBuilderRef builder = LLVMPassManagerBuilderCreate();
	LLVMPassManagerRef pass_manager = LLVMCreatePassManager();

	/* Functions calls are not supported yet, so we need to inline
	 * everything.  The most efficient way to do this is to add
	 * the always_inline attribute to all non-kernel functions
	 * and then run the Always Inline pass.  The Always Inline
	 * pass will automaically inline functions with this attribute
	 * and does not perform the expensive cost analysis that the normal
	 * inliner does.
	 */

	LLVMValueRef fn;
	for (fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
		/* All the non-kernel functions have internal linkage */
		if (LLVMGetLinkage(fn) == LLVMInternalLinkage) {
			LLVMAddFunctionAttr(fn, LLVMAlwaysInlineAttribute);
		}
	}

	LLVMAddTargetData(TD, pass_manager);
	LLVMAddAlwaysInlinerPass(pass_manager);
	LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);

	LLVMRunPassManager(pass_manager, mod);
	LLVMPassManagerBuilderDispose(builder);
	LLVMDisposePassManager(pass_manager);
	LLVMDisposeTargetData(TD);
}
Esempio n. 4
0
/**
 * Count the number of instructions in a module.
 */
unsigned
lp_build_count_ir_module(LLVMModuleRef module)
{
   LLVMValueRef func;
   unsigned num_instrs = 0;

   func = LLVMGetFirstFunction(module);
   while (func) {
      num_instrs += lp_build_count_instructions(func);
      func = LLVMGetNextFunction(func);
   }
   return num_instrs;
}
Esempio n. 5
0
int module_list_functions(void) {
  LLVMModuleRef M = load_module(false, false);
  LLVMValueRef f;

  f = LLVMGetFirstFunction(M);
  while (f) {
    if (LLVMIsDeclaration(f)) {
      printf("FunctionDeclaration: %s\n", LLVMGetValueName(f));
    } else {
      LLVMBasicBlockRef bb;
      LLVMValueRef isn;
      unsigned nisn = 0;
      unsigned nbb = 0;

      printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f),
             LLVMCountBasicBlocks(f));

      for (bb = LLVMGetFirstBasicBlock(f); bb;
           bb = LLVMGetNextBasicBlock(bb)) {
        nbb++;
        for (isn = LLVMGetFirstInstruction(bb); isn;
             isn = LLVMGetNextInstruction(isn)) {
          nisn++;
          if (LLVMIsACallInst(isn)) {
            LLVMValueRef callee =
                LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1);
            printf(" calls: %s\n", LLVMGetValueName(callee));
          }
        }
      }
      printf(" #isn: %u\n", nisn);
      printf(" #bb: %u\n\n", nbb);
    }
    f = LLVMGetNextFunction(f);
  }

  LLVMDisposeModule(M);

  return 0;
}
Esempio n. 6
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;
}