Jevin Sweval | 2 Sep 19:53 2014
Picon

Python to VHDL using LLVM; was "Re: LLVMdev Digest, Vol 123, Issue 3"

The only VHDL to LLVM project that I know of is nvc. [0] I haven't
tried it personally and from a cursory look through the source it
seems like there is a LLVM backend and a "native" backend (not sure
what that means). If you're really crazy you might want to see if you
could massage GHDL [1] (VHDL GCC frontend) + DragonEgg [2] (LLVM
backend for GCC) to get you LLVM IR.

I'm not sure about Python to LLVM. There was Unladen Swallow [3] but
that was abandoned a while ago.

Cheers,
Jevin

[0]: https://github.com/nickg/nvc
[1]: https://gna.org/projects/ghdl/
[2]: http://dragonegg.llvm.org/
[3]: https://code.google.com/p/unladen-swallow/wiki/ProjectPlan

On Mon, Sep 1, 2014 at 8:53 PM, David Blubaugh
<davidblubaugh2000 <at> yahoo.com> wrote:
> Has anyone ever did a python to LLVM to IR to VHDL compiler ???   Has anyone
> used LLVM to ultimately create a Python to VHDL compiler ???
>
> Thanks,
>
>
> David Blubaugh
>
Jonas Paulsson | 2 Sep 14:57 2014
Picon

Machine code sinking pass

Hi,

 

I ran into MachineVerifier ”Virtual register killed in block, but needed live out.”

 

It was MachineSinking:PerformTrivialForwardCoalescing() that coalesced a COPY inside a single-block loop, but left the

kill-flag and then MachineVerifier complains that a register in vregsRequired is killed in MBB.

 

In the example, %vreg520 is replaced by %vreg368 by PerformTrivialForwardCoalescing(), without clearing the kill flag:

 

BB#13: derived from LLVM BB %CF250

    Predecessors according to CFG: BB#12 BB#13 BB#14

       …

        %vreg520<def> = COPY %vreg368

        %vreg568<def,tied1> = cmp %vreg341<tied0>, %vreg520<kill>

        brr_cond <BB#13>

        brr_uncond <BB#14>

    Successors according to CFG: BB#13, BB#14

 

Into

 

BB#13: derived from LLVM BB %CF250

    Predecessors according to CFG: BB#12 BB#13 BB#14

        …

        %vreg568<def,tied1> = cmp %vreg341<tied0>, %vreg368<kill>

        brr_cond <BB#13>

        brr_uncond <BB#14>

 

=>

 

*** Bad machine code: Virtual register killed in block, but needed live out. ***

- function:    autogen_SD15028

- basic block: BB#13 CF250 (0x1c75890)

Virtual register %vreg368 is used after the block.

 

There is only one use of %vreg368 in the function.

 

One thing that strikes me is that one might want to clear the kill flag for a use inside a loop of a register defined prior to

the loop?

 

Best regards,

 

Jonas Paulsson

 

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Johnny Val | 2 Sep 12:12 2014
Picon

Instruction Selection sanity check

Hi,

I am working on a new back-end for LLVM. This architecture has two register types, data(A) and accumulator(B).

A registers are i32 where as B registers are i64. This is causing me some headaches, as far as I can tell, it's not really possible to mix the two using tablegen?

In the hardware, every instruction can either take an A register or a B register, in tablegen (as far as I can understand) this is not possible.

I ended up creating instructions like

MOV32ri (register immediate)
MOV32rr (register register)
MOV64rr, MOV64ri etc.

I've done this for essentially every instruction. This kind of works, but there are issues.

It results in unneeded copies between A registers and B registers. If a value is in an A register and the other is in a B, LLVM will do a copy between registers to make sure both registers are the same "type"(same bank) before doing the operation.

Is there any way around this? Also is it really necessary to define a different instruction for each register type (even though it's the same instruction in hardware, with the same encoding etc).

Another issue is that when multiplying, the result must always be stored in a B (accumulator register). So I did some custom lowering for the MUL node, and got the instruction to always write the result to a B register.

The problem is that later on LLVM will move it from a B register to an A register which means the result getting truncated (64 bit -> 32 bit). I am also unsure how to deal with this.

I just want to confirm that I'm doing this somewhat correctly and there isn't a much more obvious and better way of doing this.

Kind Regards,

Jonathan
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
David Blubaugh | 2 Sep 02:53 2014
Picon

Re: LLVMdev Digest, Vol 123, Issue 3

Has anyone ever did a python to LLVM to IR to VHDL compiler ???   Has anyone used LLVM to ultimately create a Python to VHDL compiler ???  

Thanks,


David Blubaugh





On Monday, September 1, 2014 8:35 PM, "llvmdev-request <at> cs.uiuc.edu" <llvmdev-request <at> cs.uiuc.edu> wrote:


Send LLVMdev mailing list submissions to
    llvmdev <at> cs.uiuc.edu

To subscribe or unsubscribe via the World Wide Web, visit
    http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
or, via email, send a message with subject or body 'help' to
    llvmdev-request <at> cs.uiuc.edu

You can reach the person managing the list at
    llvmdev-owner <at> cs.uiuc.edu

When replying, please edit your Subject line so it is more specific
than "Re: Contents of LLVMdev digest..."


Today's Topics:

  1. VMKit is retired (but you can help if you want!) (Ga?l Thomas)
  2. I nstrumenting Various Types Using Single Instrumentation
      Function (Manish Gupta)
  3. Problem linking and JITing code through C++-API (Andy Jost)
  4. Re: Instrumenting Various Types Using Single Instrumentation
      Function (John Criswell)
  5. Fwd:  understanding DAG: node creation (Dmitri Kovalenko)


----------------------------------------------------------------------

Message: 1
Date: Mon, 1 Sep 2014 21:34:58 +0200
From: Ga?l Thomas <gael.thomas00 <at> gmail.com>
To: LLVM Developers Mailing List <llvmdev <at> cs.uiuc.edu>,    Nicolas
    Geoffray <nicolas.geoffra y <at> gmail.com>
Subject: [LLVMdev] VMKit is retired (but you can help if you want!)
Message-ID:
    <CAOWuPDcZBpt_JJ5yo5YN=C+RWbtbneXB1UGd90d0mXdnrs8=RQ <at> mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

Hi all,

So, as explained in the LLVM weekly, the VMKit project is retired. It
was a very fun project, but we don't have any manpower to maintain the
code since one year. If someone is interested by restarting the
project, just send me an email, I can help to understand the
architecture of the project and how it works. I'm pretty sure that we
can also extract a Java to LLVM compiler easily (I know that some
people are interested by that).

And I want to thank all the LLVM team for their support during these
last ten (yes ten:)) years! Without their help, it wou ld have been
impossible to develop VMKit.

See you and thank you!
Ga?l



------------------------------

Message: 2
Date: Mon, 1 Sep 2014 13:50:53 -0700
From: Manish Gupta <manishg <at> cs.ucsd.edu>
To: llvmdev <llvmdev <at> cs.uiuc.edu>
Subject: [LLVMdev] Instrumenting Various Types Using Single
    Instrumentation    Function
Message-ID:
    <CAL6s+Wn0zEnUpa3ze2vMdO03PJi+8s-xo_TeOmWgoExc8xmHwg <at> mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Hi All,


My instrumentation code needs to insert calls to transmit Value list. Each
element in this list could be of different type. The list is sent to
instrumenting function say void recordVarInputValues(int num, ...) . So, I
have created a Union type in Tracing.cpp, which I link with my benchmark
module at compile time. These steps are similar to giri instrumentation
https://github.com/liuml07/giri

union NumericType
{
    int        iValue;
    long        lValue;
    double      dValue;
    ...
};

Now, I would like to convert all the llvm Values, required by
recordVarInputValues function, to be of NumericType. So that a variable
length list of NumerricType values can be passed to my instrumentation
function. This way I will not have to create different instrumentation
functions for different data types.

Can I cast say i32 value to Numeri cType value in my instrumentation code,
without inserting additional instructions in my benchmark code. I tried
inserting bitcast instructions and it doesn't work for me...

if(!CastInst::isCastable(Lvals[j]->getType(), UnionVar->getType())){
      errs()<<"CAST TO NumericType NOT POSSIBLE\n";
      exit(0);
    }
    CastInst *I = CastInst::CreateZExtOrBitCast(Lvals[j],
UnionVar->getType(), "", F);


Is this even possible or some other method will be better?

Thanks!
Manish
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140901/7454021b/attachment-0001.html>

------------------------------

Message: 3
Date : Mon, 1 Sep 2014 23:41:32 +0000
From: Andy Jost <Andrew.Jost <at> synopsys.com>
To: "LLVMdev <at> cs.uiuc.edu" <LLVMdev <at> cs.uiuc.edu>
Subject: [LLVMdev] Problem linking and JITing code through C++-API
Message-ID:
    <CD79F295D495814684E75D6407C8476284668853 <at> US01WEMBX2.internal.synopsys.com>
   
Content-Type: text/plain; charset="us-ascii"

I have a frontend that generates some LLVM bitcode that needs to be linked with other bitcode (its runtime library), which I generate from C++ source using Clang.

If I write the output of my program to disk, link it with llvm-link, and then run it with lli, everything works perfectly.  But if I try to perform the linking and running steps in my main program, I get this error during llvm::ExecutionEngine::getPointerToFunction:

Stack dump:
0.      Running pass 'X86 Machine Code Emitter' on function ' <at> .step.myappend'
1.      Running pass 'X86 Machine Code Emitter' on function ' <at> .step.myappend'
Segmentation fault (core dumped)

There are no other messages.  Any idea what I'm doing wrong?  I'll copy the source of my main C++ file and the bitcode for .step.myappend below.  I can send the full bitcode file, too, if someone asks for it, but it is around 800 lines.


####################


#include <fstream>
#include <iostream>
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Linker.h"
#include "llvm/PassManager.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "sprite/compiler.hpp"
#include "sprite/config.hpp"
#include "sprite/curryinput.hpp"
#include "sprite/icurry_parser.hpp"

namespace
{
  std::string dirname(std::string const & path)
  {
    size_t const pos = path.find_last_of("/");
    return path.substr(0, pos == std::string::npos ? 0 : pos);
  }

  std::string basename(std::string const & path)
  {
    size_t const pos = path.find_la st_of("/");
    return path.substr(pos == std::string::npos ? 0 : pos + 1);
  }

  std::string remove_extension(std::string const & path)
  {
    size_t const pos = path.find_last_of(".");
    return pos == std::string::npos ? path : path.substr(0, pos);
  }

  std::string joinpath(std::string const & dirname, std::string const & path)
  {
    if(!path.empty() && path.front() == '/')
      return path;
    if(dirname.empty())
      return path;
    return dirname.back() == '/' ? dirname + path : dirname + "/" + path;
  }
}

int main(int argc, char const *argv[])
{
  if(argc != 2)
  {
  std::cerr << "Usage: " << argv[0] << " <file.curry>" << std::endl;
    return 1;
  }
  std::string const curry2read =
      std::string(SPRITE_LIBINSTALL) + "/cmc/translator/bin/curry2read";
  std::string const curryfile(argv[1]);
  std::string const readablefile = joinpath(
      dirname(curryfile)
    , ".curry/" + remove_extension(basename(curryfile)) + ".read"
    );

  // Generate the readable Curry file.
  int ok = std::system((curry2read + " -q " + curryfile).c_str());
  if(ok != 0) return 1;
  std::ifstream input(readablefile);
  if(!input)
  {
    std::cerr << "Could not open \"" << readablefile << "\"" << std::endl;
    return 1;
  }

  // Parse the input program.
  sprite::curry::Library lib;
  input >> lib;
  std::string topmodule = lib.modules.front().name;
  // sprite::compil er::prettyprint(lib);

  // Compile the program.
  sprite::compiler::LibrarySTab stab;
  sprite::compiler::compile(lib, stab);

  // Declare the main function.
  namespace tgt = sprite::backend;
  auto & module_stab = stab.modules.at(topmodule);
  auto & compiler = *module_stab.compiler;
  tgt::scope _ = module_stab.module_ir;
  tgt::extern_(
      tgt::types::int_(32)(), "main", {}
    , [&]{
        // Construct the root expression (just the "main" symbol).
        tgt::value root_p = compiler.node_alloc();
        sprite::curry::Qname const main_{topmodule, "main"};
        root_p = construct(compiler, root_p, {main_, {}});

        // Evaluate and then print the root expression.
        compi ler.rt.normalize(root_p);
        compiler.rt.printexpr(root_p, "\n");

        tgt::return_(0);
      }
    );

  // module_stab.module_ir->dump();

  // Load the runtime library.
  llvm::OwningPtr<llvm::MemoryBuffer> buffer;
  llvm::error_code err = llvm::MemoryBuffer::getFile(
      SPRITE_LIBINSTALL "/sprite-rt.bc", buffer
    );
  if(err)
  {
    std::cerr << err.message() << std::endl;
    return EXIT_FAILURE;
  }

  // Make the runtime library into a module.
  std::string errmsg;
  llvm::Module *rtlib = llvm::ParseBitcodeFile(
      buffer.get(), module_stab.module_ir.context(), &errmsg
    );
  if(!rtlib)
  {
    std::cerr << err msg << std::endl;
    return EXIT_FAILURE;
  }

  // Link the compiled program code into the runtime module.
  bool failed = llvm::Linker::LinkModules(
      rtlib, module_stab.module_ir.ptr(), llvm::Linker::PreserveSource, &errmsg
    );
  if(failed)
  {
    std::cerr << errmsg << std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "Linking done..." << std::endl;
  rtlib->dump();

  // Run optimization passes.
  // std::vector<const char *> exportList;
  // llvm::PassManager Passes;
  // Passes.add(new llvm::DataLayout(rtlib));
  // Passes.add(llvm::createDemoteRegisterToMemoryPass());
  // Passes.add(llvm::createInternalizePass(exportList));
  // Passes.add(llvm::createScalarReplAggregatesPass());
  // Passes.add(llvm::createInstructionCombiningPass());
  // Passes.add(llvm::createGlobalOptimizerPass());
  // Passes.add(llvm::createFunctionInliningPass());
  // Passes.run(*rtlib);

  // Create the JIT
  llvm::InitializeNativeTarget();
  llvm::ExecutionEngine * jit = llvm::EngineBuilder(rtlib)
      .setErrorStr(&errmsg)
      .setEngineKind(llvm::EngineKind::JIT)
      .create();
  if(!jit)
  {
    std::cerr << "Failed to create JIT compiler: " << errmsg << std::endl;
    return EXIT_FAILURE;
  }

  // Execute the program.
  std::cout << "Begin Execution..." << std::endl;
  // rtlib->dump();
  void * main_fp = jit->getPointerToFunction(rtlib->getFunction("main"));
  int32_ t (*target_program)() = (int32_t(*)())(intptr_t)(main_fp);
  std::cout << "Ready..." << std::endl;
  return target_program();

  #if 0
  // Write a bitcode file and interpret it.
  {
    std::string err;
    llvm::raw_fd_ostream fout("sprite-out.bc", err, llvm::raw_fd_ostream::F_Binary);
    llvm::WriteBitcodeToFile(module_stab.module_ir.ptr(), fout);
  }
  std::system("llvm-link-3.3 sprite-out.bc " SPRITE_LIBINSTALL "/sprite-rt.bc > tmp.bc");
  std::system("mv tmp.bc sprite-out.bc");
  int const status = std::system("lli-3.3 sprite-out.bc");
  return WEXITSTATUS(status);
  #endif
}


####################


define linkonce void <at> .step.myappend(%"struct.sprite::compiler::node"* %root_p) {
.entry:
  %0 = alloca %"struct.sprite::compiler::node"*
  %1 = alloca %"struct.sprite ::compiler::node"*
  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0
  %2 = load %"struct.sprite::compiler::node"** %0
  %3 = getelementptr %"struct.sprite::compiler::node"* %2, i32 0, i32 2
  %4 = load i8** %3
  %5 = bitcast i8* %4 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %5, %"struct.sprite::compiler::node"** %0
  br label %11

; <label>:6                                      ; preds = %11
  %7 = load %"struct.sprite::compiler::node"** %0
  %8 = getelementptr %"struct.sprite::compiler::node"* %7, i32 0, i32 2
  %9 = load i8** %8
  %10 = bitcast i8* %9 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %10, %"struct.s prite::compiler::node"** %0
  br label %11, !sprite.implied !0

; <label>:11                                      ; preds = %6, %.entry
  %12 = load %"struct.sprite::compiler::node"** %0
  %13 = getelementptr %"struct.sprite::compiler::node"* %12, i32 0, i32 1
  %14 = load i64* %13
  %15 = load i64* %13
  %16 = icmp eq i64 %15, -3
  br i1 %16, label %6, label %17

; <label>:17                                      ; preds = %11
  %18 = load %"struct.sprite::compiler::node"** %0
  store %"struct.sprite::compiler::node"* %18, %"struct.sprite::compiler::node"** %1
  %19 = getelementptr %"struct.sprite::compiler::node"* %18, i32 0, i32 1
  %20 = load i64* %19  %21 = add i64 %20, 4
  %22 = getelementptr [6 x i8*]* <at> .jtable, i32 0, i64 %21
  %23 = load i8** %22
  indirectbr i8* %23, [label %24, label %26, label %36, label %38, label %44, label %66]

; <label>:24                                      ; preds = %26, %17
  %25 = call i32 (i8*, ...)* <at> printf(i8* getelementptr inbounds ([16 x i8]* <at> .str21, i32 0, i32 0))
  ret void, !case...FAIL !1

; <label>:26                                      ; preds = %26, %17
  %27 = load %"struct.sprite::compiler::node"** %1
  %28 = getelementptr %"struct.sprite::compiler::node"* %27, i32 0, i32 2
  %29 = load i8** %28
  %30 = bitcast i8* %29 to %"struct.sprite::compiler::node"*
&nb sp; store %"struct.sprite::compiler::node"* %30, %"struct.sprite::compiler::node"** %1
  %31 = getelementptr %"struct.sprite::compiler::node"* %30, i32 0, i32 1
  %32 = load i64* %31
  %33 = add i64 %32, 4
  %34 = getelementptr [6 x i8*]* <at> .jtable, i32 0, i64 %33
  %35 = load i8** %34
  indirectbr i8* %35, [label %24, label %26, label %36, label %38, label %44, label %66]

; <label>:36                                      ; preds = %26, %17
  %37 = call i32 (i8*, ...)* <at> printf(i8* getelementptr inbounds ([18 x i8]* <at> .str22, i32 0, i32 0))
  ret void, !case...CHOICE !1

; <label>:38                                      ; preds = %26, %17
  %39 = load %"struct.sprite::compi ler::node"** %1
  %40 = getelementptr %"struct.sprite::compiler::node"* %39, i32 0, i32 0
  %41 = load %"struct.sprite::compiler::vtable"** %40
  %42 = getelementptr %"struct.sprite::compiler::vtable"* %41, i32 0, i32 4
  %43 = load void (%"struct.sprite::compiler::node"*)** %42
  tail call void %43(%"struct.sprite::compiler::node"* %39)
  ret void

; <label>:44                                      ; preds = %26, %17
  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0
  %45 = load %"struct.sprite::compiler::node"** %0
  %46 = getelementptr %"struct.sprite::compiler::node"* %45, i32 0, i32 3
  %47 = load i8** %46
  %48 = bitcast i8* %47 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler: :node"* %48, %"struct.sprite::compiler::node"** %0
  br label %54

; <label>:49                                      ; preds = %54
  %50 = load %"struct.sprite::compiler::node"** %0
  %51 = getelementptr %"struct.sprite::compiler::node"* %50, i32 0, i32 2
  %52 = load i8** %51
  %53 = bitcast i8* %52 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %53, %"struct.sprite::compiler::node"** %0
  br label %54, !sprite.implied !0

; <label>:54                                      ; preds = %49, %44
  %55 = load %"struct.sprite::compiler::node"** %0
  %56 = getelementptr %"struct.sprite::compiler::node"* %55, i32 0, i32 1
  %57 = load i64* %5 6
  %58 = load i64* %56
  %59 = icmp eq i64 %58, -3
  br i1 %59, label %49, label %60

; <label>:60                                      ; preds = %54
  %61 = load %"struct.sprite::compiler::node"** %0
  %62 = bitcast %"struct.sprite::compiler::node"* %61 to i8*
  %63 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 0
  store %"struct.sprite::compiler::vtable"* <at> .fwd.vt, %"struct.sprite::compiler::vtable"** %63
  %64 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 1
  store i64 -3, i64* %64
  %65 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 2
  store i8* %62, i8** %65
  ret void

; <label>:66                      &nb sp;               ; preds = %26, %17
  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0
  %67 = load %"struct.sprite::compiler::node"** %0
  %68 = getelementptr %"struct.sprite::compiler::node"* %67, i32 0, i32 2
  %69 = load i8** %68
  %70 = bitcast i8* %69 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %70, %"struct.sprite::compiler::node"** %0
  br label %76

; <label>:71                                      ; preds = %76
  %72 = load %"struct.sprite::compiler::node"** %0
  %73 = getelementptr %"struct.sprite::compiler::node"* %72, i32 0, i32 2
  %74 = load i8** %73
  %75 = bitcast i8* %74 to %"struct.sprite::compiler::node"*
  store %"struct.spr ite::compiler::node"* %75, %"struct.sprite::compiler::node"** %0
  br label %76, !sprite.implied !0

; <label>:76                                      ; preds = %71, %66
  %77 = load %"struct.sprite::compiler::node"** %0
  %78 = getelementptr %"struct.sprite::compiler::node"* %77, i32 0, i32 1
  %79 = load i64* %78
  %80 = load i64* %78
  %81 = icmp eq i64 %80, -3
  br i1 %81, label %71, label %82

; <label>:82                                      ; preds = %76
  %83 = load %"struct.sprite::compiler::node"** %0
  %84 = getelementptr %"struct.sprite::compiler::node"* %83, i32 0, i32 2
  %85 = load i8** %84
  %86 = bitcast i8* %85 to %"struct.sprite::compiler ::node"*
  store %"struct.sprite::compiler::node"* %86, %"struct.sprite::compiler::node"** %0
  br label %92

; <label>:87                                      ; preds = %92
  %88 = load %"struct.sprite::compiler::node"** %0
  %89 = getelementptr %"struct.sprite::compiler::node"* %88, i32 0, i32 2
  %90 = load i8** %89
  %91 = bitcast i8* %90 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %91, %"struct.sprite::compiler::node"** %0
  br label %92, !sprite.implied !0

; <label>:92                                      ; preds = %87, %82
  %93 = load %"struct.sprite::compiler::node"** %0
  %94 = getelementptr %"struct.sprite::compile r::node"* %93, i32 0, i32 1
  %95 = load i64* %94
  %96 = load i64* %94
  %97 = icmp eq i64 %96, -3
  br i1 %97, label %87, label %98

; <label>:98                                      ; preds = %92
  %99 = load %"struct.sprite::compiler::node"** %0
  %100 = bitcast %"struct.sprite::compiler::node"* %99 to i8*
  %101 = call i8* <at> malloc(i64 32)
  %102 = bitcast i8* %101 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0
  %103 = load %"struct.sprite::compiler::node"** %0
  %104 = getelementptr %"struct.sprite::compiler::node"* %103, i32 0, i32 2
  %105 = load i8** %104
  %106 = bitcast i8* %105 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::comp iler::node"* %106, %"struct.sprite::compiler::node"** %0
  br label %112

; <label>:107                                    ; preds = %112
  %108 = load %"struct.sprite::compiler::node"** %0
  %109 = getelementptr %"struct.sprite::compiler::node"* %108, i32 0, i32 2
  %110 = load i8** %109
  %111 = bitcast i8* %110 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %111, %"struct.sprite::compiler::node"** %0
  br label %112, !sprite.implied !0

; <label>:112                                    ; preds = %107, %98
  %113 = load %"struct.sprite::compiler::node"** %0
  %114 = getelementptr %"struct.sprite::compiler::node"* %113, i32 0, i32 1
  % 115 = load i64* %114
  %116 = load i64* %114
  %117 = icmp eq i64 %116, -3
  br i1 %117, label %107, label %118

; <label>:118                                    ; preds = %112
  %119 = load %"struct.sprite::compiler::node"** %0
  %120 = getelementptr %"struct.sprite::compiler::node"* %119, i32 0, i32 3
  %121 = load i8** %120
  %122 = bitcast i8* %121 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %122, %"struct.sprite::compiler::node"** %0
  br label %128

; <label>:123                                    ; preds = %128
  %124 = load %"struct.sprite::compiler::node"** %0
  %125 = getelementptr %"struct.sprite::compiler::node"* %124, i32 0, i32 2
  %126 = load i8** %125
  %127 = bitcast i8* %126 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %127, %"struct.sprite::compiler::node"** %0
  br label %128, !sprite.implied !0

; <label>:128                                    ; preds = %123, %118
  %129 = load %"struct.sprite::compiler::node"** %0
  %130 = getelementptr %"struct.sprite::compiler::node"* %129, i32 0, i32 1
  %131 = load i64* %130
  %132 = load i64* %130
  %133 = icmp eq i64 %132, -3
  br i1 %133, label %123, label %134

; <label>:134                                    ; preds = %128
  %135 = load %"struct.sprite::compiler::node"** %0
  %136 = b itcast %"struct.sprite::compiler::node"* %135 to i8*
  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0
  %137 = load %"struct.sprite::compiler::node"** %0
  %138 = getelementptr %"struct.sprite::compiler::node"* %137, i32 0, i32 3
  %139 = load i8** %138
  %140 = bitcast i8* %139 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::compiler::node"* %140, %"struct.sprite::compiler::node"** %0
  br label %146

; <label>:141                                    ; preds = %146
  %142 = load %"struct.sprite::compiler::node"** %0
  %143 = getelementptr %"struct.sprite::compiler::node"* %142, i32 0, i32 2
  %144 = load i8** %143
  %145 = bitcast i8* %144 to %"struct.sprite::compiler::node"*
  store %"struct.sprite::com piler::node"* %145, %"struct.sprite::compiler::node"** %0
  br label %146, !sprite.implied !0

; <label>:146                                    ; preds = %141, %134
  %147 = load %"struct.sprite::compiler::node"** %0
  %148 = getelementptr %"struct.sprite::compiler::node"* %147, i32 0, i32 1
  %149 = load i64* %148
  %150 = load i64* %148
  %151 = icmp eq i64 %150, -3
  br i1 %151, label %141, label %152

; <label>:152                                    ; preds = %146
  %153 = load %"struct.sprite::compiler::node"** %0
  %154 = bitcast %"struct.sprite::compiler::node"* %153 to i8*
  %155 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 0
  st ore %"struct.sprite::compiler::vtable"* <at> .vtable.for.myappend, %"struct.sprite::compiler::vtable"** %155
  %156 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 1
  store i64 -1, i64* %156
  %157 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 2
  store i8* %136, i8** %157
  %158 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 3
  store i8* %154, i8** %158
  %159 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 0
  store %"struct.sprite::compiler::vtable"* <at> .vt.CTOR.MyCons, %"struct.sprite::compiler::vtable"** %159
  %160 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 1
  store i64 1, i64* %160
  %161 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 2
  store i8* %100, i8** %161
  %162 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 3
  store i8* %101, i8** %162
  ret void
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140901/52547f6a/attachment-0001.html>

------------------------------

Message: 4
Date: Mon, 01 Sep 2014 20:13:56 -0400
From: John Criswell <jtcriswel <at> gmail.com>
To: manishg <at> cs.ucsd.edu, llvmdev <llvmdev <at> cs.uiuc.edu>
Subject: Re: [LLVMdev] Instrumenting Various Types Using Single
    Instrumentation Function
Message-ID: <54050BC4.8060405 <at> gmail.com>
Content-Type: text/plain; charset="iso-8859-1"; Format="flowed"

Dear Manish,

Union types in LLVM are points to structures, so casting 8, 16, 32, and
64 bit values to a union pointer is probably not what you want.

I think the easiest thing to do is to:

1) Change the function in your run-time library to take the largest
integer size supported by your target.

2) Change the instrumentation code to cast all values (including
pointers) to this type.

I'm not sure if CastInst::isCastable() is what you want to use to check
to see that the casting can be done.  I would just go ahead and use the
bit-cast since, for the call, you should always be casting fr om a type
with lower bit-width to higher bit-width.  If you enable assertions when
you build LLVM, then you should get an assertion if you try to create a
Bitcast instruction that isn't going to work.

Regards,

John Criswell


On 9/1/14, 4:50 PM, Manish Gupta wrote:
> Hi All,
>
>
> My instrumentation code needs to insert calls to transmit Value list.
> Each element in this list could be of different type. The list is sent
> to instrumenting function say void recordVarInputValues(int num, ...)
> . So, I have created a Union type in Tracing.cpp, which I link with my
> benchmark module at compile time. These steps are similar to giri
> instrumentation https://github.com/liuml07/giri
>
> union NumericType
> {
>    int        iValue;
>&nbsp ;   long        lValue;
>    double      dValue;
>      ...
> };
>
> Now, I would like to convert all the llvm Values, required by
> recordVarInputValues function, to be of NumericType. So that a
> variable length list of NumerricType values can be passed to my
> instrumentation function. This way I will not have to create different
> instrumentation functions for different data types.
>
> Can I cast say i32 value to NumericType value in my instrumentation
> code, without inserting additional instructions in my benchmark code.
> I tried inserting bitcast instructions and it doesn't work for me...
>
> if(!CastInst::isCastable(Lvals[j]->getType(), UnionVar->getType())){
>      errs()<<"CAST TO NumericType NOT POSSIBLE\n";
>      exit(0);>    }
>    CastInst *I = CastInst::CreateZExtOrBitCast(Lvals[j],
> UnionVar->getType(), "", F);
>
> Is this even possible or some other method will be better?
>
> Thanks!
> Manish
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev <at> cs.uiuc.edu        http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cs.uiuc.edu/piperma il/llvmdev/attachments/20140901/23a75e18/attachment-0001.html>

------------------------------

Message: 5
Date: Tue, 2 Sep 2014 04:26:52 +0400
From: Dmitri Kovalenko <dmitri.a.kovalenko <at> gmail.com>
To: "llvmdev <at> cs.uiuc.edu" <llvmdev <at> cs.uiuc.edu>
Subject: [LLVMdev] Fwd:  understanding DAG: node creation
Message-ID:
    <CAF+j+H_Q42PA63odeQOWwsuL6O-M2NRnB4bRn5ZxRq0Mn4rW+Q <at> mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Sam, that helped. Thank you so much.


2014-09-01 19:04 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk>:

Hi,
>
> I would still switch chain operands to be the last ones and ensure that
> lxacc result type is (MVT::i32, MVT::other) and not the other way around.
>
> good luck,
>
> sam
>
> Sam Parker
> Research Student
> Electronic System Design Group
> School of Electronic, Electrical and Systems Engineering
> Loughborough University
> UK
>
> On 01/09/14 15:39, Dmitri Kovalenko wrote:
>
>  Yes, I'm going to provide it. I believe there must be no additional
> work on the scheduling phase. It's just some mistake in the instruction
> definition or DAG.
>
>  I create Nodes inside SelectionDAGBuilder::visitIntrinicCall like that:
>
>  case Intrinsic::sparc_xmac: {
>    SDVTList nodeTys = DAG.getVTList( MVT::Other, MVT::i32);
>    SDValue Ops[3];
>    Ops[0] = getRoot();
>    Ops[1] = getValue(I.getArgOperand(0));
>    Ops[2] = getValue(I.getArgOperand(1));
>    SDValue xmacCall = DAG.getNode(ISD::XMAC, sdl, nodeTys, Ops);
>    DAG.setRoot(xmacCall.getValue(0));
>    return nullptr;
>  }
>  case Intrinsic::sparc_srxacc: {
>    SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
>    SDValue Ops[2];
>    Ops[0] = getRoot();
>    Ops[1] = getValue(I.getArgOperand(0));
>    SDValue srCall = DAG.getNode(ISD::SRXACC, sdl, nodeTys, Ops);
>    DAG.setRoot(srCall.getValue(0));
>    return nullptr;
>  }
>  case Intrinsic::sparc_lrxacc: {
&g t;    SDVTList nodeTys = DAG.getVTList(MVT::Other,MVT::i32);
>    SDValue Ops[1];
>    Ops[0] = getRoot();
>    SDValue lrCall = DAG.getNode(ISD::LRXACC, sdl,
>                                  nodeTys, Ops);
>    DAG.setRoot(lrCall.getValue(0));
>    setValue(&I, lrCall.getValue(1));
>    return nullptr;
>  }
>
> Then, lower them trivially.
>
> setOperationAction(ISD::LRXACC, MVT::Other, Legal);
> setOperationAction(ISD::SRXACC, MVT::Other, Legal);
> setOperationAction(ISD::XMAC, MVT::Other, Legal);
>
>  Then, just set respective instr opcodes in SparcDAGToDAGISel::Select:
>
>  case ISD::SRXACC: {
>    SDVTList nodeTys = CurDAG->getVTList(MVT::O ther);
>
>    SDValue Ops[2];
>    Ops[0] = N->getOperand(0);
>    Ops[1] = N->getOperand(1);
>
>    return CurDAG->SelectNodeTo(N, SP::SRXACC, nodeTys, Ops);
>  }
>  case ISD::XMAC: {
>    SDVTList nodeTys = CurDAG->getVTList(MVT::Other);
>
>    SDValue Ops[3];
>    Ops[0] = N->getOperand(0);
>    Ops[1] = N->getOperand(1);
>    Ops[2] = N->getOperand(2);
>
>    return CurDAG->SelectNodeTo(N, SP::XMAC, nodeTys, Ops);
>  }
>  case ISD::LRXACC: {
>    SDVTList nodeTys = CurDAG->getVTList(MVT::Other, MVT::i32);
>    SDValue Ops[1];
>    Ops[0] = N->getOperand(0);
>    return CurDAG->Sele ctNodeTo(N, SP::LRXACC, nodeTys, Ops);
>  }
>
>  They declared as:
> def XMAC : F3_1<2, 0b111111,
>                      (outs),
>                      (ins IntRegs:$rs1, IntRegs:$rs2),
>                      "xmac $rs1, $rs2, %xacc",
>                      []>;
>
> let rs1 = 0, rd = 1, Uses=[XACC] in
> def LRXACC : F3_1<2, 0b101110,
>                  (outs IntRegs:$rd), (ins),
>                  "lrxacc %xacc, $rd", []>;
>
> let rd = 0, Defs=[XACC] in
> def SRXACC : F3_1<2, 0b011101,
>        & nbsp;           (outs), (ins IntRegs:$rs1),
>                    "srxacc $rs1, %xacc", []>;
>
>  While my register is declared as:
> def XACC : Ri<88, "XACC">, DwarfRegNum<[88]>;
>
>  Please, note:
> My problem is of self-educational and investigative nature.
>  This instruction srxacc and register xacc are not real.
>  Produced code aren't supposed to work anywhere.
>  I just need llc to be able to output assembly file.
>  Thanks for your insights.
>
>
> 2014-09-01 18:26 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk>:
>
>>  Hi,
>> I'm not sure. But in your lowered DAG the chain nodes are the first
>> operands for you custom nodes , however for the other nodes the chain is the
>> last operand. I seem to remember that during targetlowering the chain is
>> the first operand and then it seems to switch over after ISelDAG, this
>> confused me and may have something to do with the issue that you are
>> seeing. I really don't know much about scheduling, do you want to post your
>> instruction definitions again to see if someone else has some ideas,.
>>
>> cheers,
>> sam
>>
>> Sam Parker
>> Research Student
>> Electronic System Design Group
>> School of Electronic, Electrical and Systems Engineering
>> Loughborough University
>> UK
>>
>>  On 01/09/14 14:35, Dmitri Kovalenko wrote:
>>
>>    Before I wrote here, I tried both ways you decsribed, but none of
>> them has worked out for me.
> >  With yours sugesstions I was able to move a bit further with the first
>> approach (when we don't create regclass and just hard-code it in .td)
>>
>>  But I still receive strange errors. I received DAG which I happy with
>> (DAG here: http://goo.gl/62tpkk), but everything goes broken on
>> scheduling.
>>
>>  I had to chain mine nodes, because otherwise nodes xmac and srxacc got
>> removed on first combine. But since they are chained, they have MVT::Other
>> return type, and that causes strange crash inside func GetCostFor in
>> ScheduleDAGRRList.cpp:
>>
>> Def RegClass = TLI->getRepRegClassFor(VT)->getID();
>>  When VT is MVT::Other it returns 0x0, what results crash.
>>
>>  It got me confused, because reading documentation o n CodeGen gave me an
>> idea, that chain edges are control flow edges, not data edges. So I don't
>> understand why scheduler tries to assign some register to it.
>>
>>  I'm struggling with this problem way to long for now, and I very
>> appreciate yours help, Sam.
>>
>>
>>
>>  2014-09-01 1:50 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk>:
>>
>>> Hi,
>>>
>>> Yes, that's what I would do. If you want LLVM and the register allocator
>>> to also know that the instruction explicitly defines the register, I would
>>> designate the register into it's own register class and have your
>>> instruction write to that class (and there will be only a single option for
>>> RA).
>>>
&g t;>> cheers,
>>> Sam
>>>
>>> Sam Parker
>>> Research Student
>>> Electronic Systems Design Group
>>>  Loughborough University
>>> UK
>>>
>>> ________________________________________
>>> From: Dmitri Kovalenko [dmitri.a.kovalenko <at> gmail.com]
>>> Sent: 31 August 2014 21:53
>>> To: Sam Parker
>>> Cc: llvmdev <at> cs.uiuc.edu
>>> Subject: Re: [LLVMdev] understanding DAG: node creation
>>>
>>> Sam, thanks for your answer.
>>> That's a great suggestion.
>>>
>>> And excuse me for maybe dilettante question:
>>> To hard-code use of the glob al register means to hard-code it in the
>>> 'asm string' argument of the instruction definition in the .td file?
>>>
>>>
>>>  2014-09-01 0:44 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk<mailto:
>>> S.Parker3 <at> lboro.ac.uk>>:
>>> Hi Dmitri,
>>>
>>> If you have such a simple intrinsic which operates on a single
>>> register,  just lower the intrinsic to a target specific node which is only
>>> implemented by a single instruction. Like you were doing before and by
>>> using a chain operand. Hard code the instruction to use and define the
>>> global register and only pass the instruction the actual variable argument.
>>>
>>> Hope that helps,
>>> Sam
>>>
>>> Sam Parker
>>> Research Student
>>> Electronic Systems Design Group
>>> School of Electronic, Electrical and Systems Engineering
>>> Loughborough University
>>>
>>> ----- Reply message -----
>>>  From: "Dmitri Kovalenko" <dmitri.a.kovalenko <at> gmail.com<mailto:
>>> dmitri.a.kovalenko <at> gmail.com>>
>>> To: <llvmdev <at> cs.uiuc.edu<mailto:llvmdev <at> cs.uiuc.edu>&gt ;
>>> Subject: [LLVMdev] understanding DAG: node creation
>>> Date: Sat, Aug 30, 2014 22:18
>>>
>>>
>>> I have an intrinsic and it must be lowered to instruction, which works
>>> with fixed register.
>>> So, it takes contents of this register and another argument as input.
>>> After execution, the result of the instruction is placed into that same
>>> fixed register.
>>>
>>> What should I do in SelectionDAGBuilder::visitIntrinicCall to describe
>>> such behaviour for a SDNode?
>>>
>>> Thank you for the ideas and insights.
>>>
>>> --
>>> Sincerely,
>>> Dmitri Kovalenko
>>>
>>>
>>>
>>> --
>>> Sincerely,
>>> Dmitri Kovalenko
>>>
>>
>>
> >
>> --
>> Sincerely,
>> Dmitri Kovalenko
>>
>>
>>
>
>
> --
> Sincerely,
> Dmitri Kovalenko
>
>
>


--
Sincerely,
Dmitri Kovalenko



--
Sincerely,
Dmitri Kovalenko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140902/7bf3b7e8/attachment.html>

------------------------------

_______________________________________________
LLVMdev mailing list
LLVMdev <at> cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


End of LLVMdev Digest, Vol 123, Issue 3
***************************************


_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Dmitri Kovalenko | 2 Sep 02:26 2014
Picon

Fwd: understanding DAG: node creation



Sam, that helped. Thank you so much.


2014-09-01 19:04 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk>:

Hi,

I would still switch chain operands to be the last ones and ensure that lxacc result type is (MVT::i32, MVT::other) and not the other way around.

good luck,

sam

Sam Parker Research Student Electronic System Design Group School of Electronic, Electrical and Systems Engineering Loughborough University UK
On 01/09/14 15:39, Dmitri Kovalenko wrote:
Yes, I'm going to provide it. I believe there must be no additional work on the scheduling phase. It's just some mistake in the instruction definition or DAG.

I create Nodes inside SelectionDAGBuilder::visitIntrinicCall like that:

  case Intrinsic::sparc_xmac: {
    SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
    SDValue Ops[3];
    Ops[0] = getRoot();
    Ops[1] = getValue(I.getArgOperand(0));
    Ops[2] = getValue(I.getArgOperand(1));
    SDValue xmacCall = DAG.getNode(ISD::XMAC, sdl, nodeTys, Ops);
    DAG.setRoot(xmacCall.getValue(0));
    return nullptr;
  }
  case Intrinsic::sparc_srxacc: {
    SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
    SDValue Ops[2];
    Ops[0] = getRoot();
    Ops[1] = getValue(I.getArgOperand(0));
    SDValue srCall = DAG.getNode(ISD::SRXACC, sdl, nodeTys, Ops);
    DAG.setRoot(srCall.getValue(0));
    return nullptr;
  }
  case Intrinsic::sparc_lrxacc: {
    SDVTList nodeTys = DAG.getVTList(MVT::Other,MVT::i32);
    SDValue Ops[1];
    Ops[0] = getRoot();
    SDValue lrCall = DAG.getNode(ISD::LRXACC, sdl,
                                 nodeTys, Ops);
    DAG.setRoot(lrCall.getValue(0));
    setValue(&I, lrCall.getValue(1));
    return nullptr;
  }

Then, lower them trivially.

setOperationAction(ISD::LRXACC, MVT::Other, Legal);
setOperationAction(ISD::SRXACC, MVT::Other, Legal);
setOperationAction(ISD::XMAC, MVT::Other, Legal);

Then, just set respective instr opcodes in SparcDAGToDAGISel::Select:

  case ISD::SRXACC: {
    SDVTList nodeTys = CurDAG->getVTList(MVT::Other);

    SDValue Ops[2];
    Ops[0] = N->getOperand(0);
    Ops[1] = N->getOperand(1);

    return CurDAG->SelectNodeTo(N, SP::SRXACC, nodeTys, Ops);
  }
  case ISD::XMAC: {
    SDVTList nodeTys = CurDAG->getVTList(MVT::Other);

    SDValue Ops[3];
    Ops[0] = N->getOperand(0);
    Ops[1] = N->getOperand(1);
    Ops[2] = N->getOperand(2);
   
    return CurDAG->SelectNodeTo(N, SP::XMAC, nodeTys, Ops);
  }
  case ISD::LRXACC: {
    SDVTList nodeTys = CurDAG->getVTList(MVT::Other, MVT::i32);
    SDValue Ops[1];
    Ops[0] = N->getOperand(0);
    return CurDAG->SelectNodeTo(N, SP::LRXACC, nodeTys, Ops);
 }

They declared as:
def XMAC : F3_1<2, 0b111111,
                      (outs),
                      (ins IntRegs:$rs1, IntRegs:$rs2),
                      "xmac $rs1, $rs2, %xacc",
                      []>;

let rs1 = 0, rd = 1, Uses=[XACC] in
def LRXACC : F3_1<2, 0b101110,
                 (outs IntRegs:$rd), (ins),
                 "lrxacc %xacc, $rd", []>;

let rd = 0, Defs=[XACC] in
def SRXACC : F3_1<2, 0b011101,
                   (outs), (ins IntRegs:$rs1),
                   "srxacc $rs1, %xacc", []>;

While my register is declared as:
def XACC : Ri<88, "XACC">, DwarfRegNum<[88]>;

Please, note:
My problem is of self-educational and investigative nature.
This instruction srxacc and register xacc are not real.
Produced code aren't supposed to work anywhere.
I just need llc to be able to output assembly file.
Thanks for your insights.


2014-09-01 18:26 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk>:
Hi,
I'm not sure. But in your lowered DAG the chain nodes are the first operands for you custom nodes, however for the other nodes the chain is the last operand. I seem to remember that during targetlowering the chain is the first operand and then it seems to switch over after ISelDAG, this confused me and may have something to do with the issue that you are seeing. I really don't know much about scheduling, do you want to post your instruction definitions again to see if someone else has some ideas,.

cheers,
sam
Sam Parker Research Student Electronic System Design Group School of Electronic, Electrical and Systems Engineering Loughborough University UK
On 01/09/14 14:35, Dmitri Kovalenko wrote:
Before I wrote here, I tried both ways you decsribed, but none of them has worked out for me.
With yours sugesstions I was able to move a bit further with the first approach (when we don't create regclass and just hard-code it in .td)

But I still receive strange errors. I received DAG which I happy with (DAG here: http://goo.gl/62tpkk), but everything goes broken on scheduling.

I had to chain mine nodes, because otherwise nodes xmac and srxacc got removed on first combine. But since they are chained, they have MVT::Other return type, and that causes strange crash inside func GetCostFor in ScheduleDAGRRList.cpp:

Def RegClass = TLI->getRepRegClassFor(VT)->getID();
When VT is MVT::Other it returns 0x0, what results crash.

It got me confused, because reading documentation on CodeGen gave me an idea, that chain edges are control flow edges, not data edges. So I don't understand why scheduler tries to assign some register to it.

I'm struggling with this problem way to long for now, and I very appreciate yours help, Sam.



2014-09-01 1:50 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk>:
Hi,

Yes, that's what I would do. If you want LLVM and the register allocator to also know that the instruction explicitly defines the register, I would designate the register into it's own register class and have your instruction write to that class (and there will be only a single option for RA).

cheers,
Sam

Sam Parker
Research Student
Electronic Systems Design Group
Loughborough University
UK

________________________________________
From: Dmitri Kovalenko [dmitri.a.kovalenko <at> gmail.com]
Sent: 31 August 2014 21:53
To: Sam Parker
Cc: llvmdev <at> cs.uiuc.edu
Subject: Re: [LLVMdev] understanding DAG: node creation

Sam, thanks for your answer.
That's a great suggestion.

And excuse me for maybe dilettante question:
To hard-code use of the global register means to hard-code it in the 'asm string' argument of the instruction definition in the .td file?


2014-09-01 0:44 GMT+04:00 Sam Parker <S.Parker3 <at> lboro.ac.uk<mailto:S.Parker3 <at> lboro.ac.uk>>:
Hi Dmitri,

If you have such a simple intrinsic which operates on a single register,  just lower the intrinsic to a target specific node which is only implemented by a single instruction. Like you were doing before and by using a chain operand. Hard code the instruction to use and define the global register and only pass the instruction the actual variable argument.

Hope that helps,
Sam

Sam Parker
Research Student
Electronic Systems Design Group
School of Electronic, Electrical and Systems Engineering
Loughborough University

----- Reply message -----
From: "Dmitri Kovalenko" <dmitri.a.kovalenko <at> gmail.com<mailto:dmitri.a.kovalenko <at> gmail.com>>
To: <llvmdev <at> cs.uiuc.edu<mailto:llvmdev <at> cs.uiuc.edu>>
Subject: [LLVMdev] understanding DAG: node creation
Date: Sat, Aug 30, 2014 22:18


I have an intrinsic and it must be lowered to instruction, which works with fixed register.
So, it takes contents of this register and another argument as input. After execution, the result of the instruction is placed into that same fixed register.

What should I do in SelectionDAGBuilder::visitIntrinicCall to describe such behaviour for a SDNode?

Thank you for the ideas and insights.

--
Sincerely,
Dmitri Kovalenko



--
Sincerely,
Dmitri Kovalenko



--
Sincerely,
Dmitri Kovalenko




--
Sincerely,
Dmitri Kovalenko




--
Sincerely,
Dmitri Kovalenko



--
Sincerely,
Dmitri Kovalenko
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Andy Jost | 2 Sep 01:41 2014

Problem linking and JITing code through C++-API

I have a frontend that generates some LLVM bitcode that needs to be linked with other bitcode (its runtime library), which I generate from C++ source using Clang.

 

If I write the output of my program to disk, link it with llvm-link, and then run it with lli, everything works perfectly.  But if I try to perform the linking and running steps in my main program, I get this error during llvm::ExecutionEngine::getPointerToFunction:

 

Stack dump:

0.      Running pass 'X86 Machine Code Emitter' on function ' <at> .step.myappend'

1.      Running pass 'X86 Machine Code Emitter' on function ' <at> .step.myappend'

Segmentation fault (core dumped)

 

There are no other messages.  Any idea what I’m doing wrong?  I’ll copy the source of my main C++ file and the bitcode for .step.myappend below.  I can send the full bitcode file, too, if someone asks for it, but it is around 800 lines.

 

 

####################

 

 

#include <fstream>

#include <iostream>

#include "llvm/Bitcode/ReaderWriter.h"

#include "llvm/ExecutionEngine/JIT.h"

#include "llvm/IR/DataLayout.h"

#include "llvm/Linker.h"

#include "llvm/PassManager.h"

#include "llvm/Support/MemoryBuffer.h"

#include "llvm/Support/raw_ostream.h"

#include "llvm/Support/system_error.h"

#include "llvm/Support/TargetSelect.h"

#include "llvm/Transforms/IPO.h"

#include "llvm/Transforms/Scalar.h"

#include "sprite/compiler.hpp"

#include "sprite/config.hpp"

#include "sprite/curryinput.hpp"

#include "sprite/icurry_parser.hpp"

 

namespace

{

  std::string dirname(std::string const & path)

  {

    size_t const pos = path.find_last_of("/");

    return path.substr(0, pos == std::string::npos ? 0 : pos);

  }

 

  std::string basename(std::string const & path)

  {

    size_t const pos = path.find_last_of("/");

    return path.substr(pos == std::string::npos ? 0 : pos + 1);

  }

 

  std::string remove_extension(std::string const & path)

  {

    size_t const pos = path.find_last_of(".");

    return pos == std::string::npos ? path : path.substr(0, pos);

  }

 

  std::string joinpath(std::string const & dirname, std::string const & path)

  {

    if(!path.empty() && path.front() == '/')

      return path;

    if(dirname.empty())

      return path;

    return dirname.back() == '/' ? dirname + path : dirname + "/" + path;

  }

}

 

int main(int argc, char const *argv[])

{

  if(argc != 2)

  {

   std::cerr << "Usage: " << argv[0] << " <file.curry>" << std::endl;

    return 1;

  }

 

  std::string const curry2read =

      std::string(SPRITE_LIBINSTALL) + "/cmc/translator/bin/curry2read";

  std::string const curryfile(argv[1]);

  std::string const readablefile = joinpath(

      dirname(curryfile)

    , ".curry/" + remove_extension(basename(curryfile)) + ".read"

    );

 

  // Generate the readable Curry file.

  int ok = std::system((curry2read + " -q " + curryfile).c_str());

  if(ok != 0) return 1;

  std::ifstream input(readablefile);

  if(!input)

  {

    std::cerr << "Could not open \"" << readablefile << "\"" << std::endl;

    return 1;

  }

 

  // Parse the input program.

  sprite::curry::Library lib;

  input >> lib;

  std::string topmodule = lib.modules.front().name;

  // sprite::compiler::prettyprint(lib);

 

  // Compile the program.

  sprite::compiler::LibrarySTab stab;

  sprite::compiler::compile(lib, stab);

 

  // Declare the main function.

  namespace tgt = sprite::backend;

  auto & module_stab = stab.modules.at(topmodule);

  auto & compiler = *module_stab.compiler;

  tgt::scope _ = module_stab.module_ir;

  tgt::extern_(

      tgt::types::int_(32)(), "main", {}

    , [&]{

        // Construct the root expression (just the "main" symbol).

        tgt::value root_p = compiler.node_alloc();

        sprite::curry::Qname const main_{topmodule, "main"};

        root_p = construct(compiler, root_p, {main_, {}});

 

        // Evaluate and then print the root expression.

        compiler.rt.normalize(root_p);

        compiler.rt.printexpr(root_p, "\n");

 

        tgt::return_(0);

      }

    );

 

  // module_stab.module_ir->dump();

 

  // Load the runtime library.

  llvm::OwningPtr<llvm::MemoryBuffer> buffer;

  llvm::error_code err = llvm::MemoryBuffer::getFile(

      SPRITE_LIBINSTALL "/sprite-rt.bc", buffer

    );

  if(err)

  {

    std::cerr << err.message() << std::endl;

    return EXIT_FAILURE;

  }

 

  // Make the runtime library into a module.

  std::string errmsg;

  llvm::Module *rtlib = llvm::ParseBitcodeFile(

      buffer.get(), module_stab.module_ir.context(), &errmsg

    );

  if(!rtlib)

  {

    std::cerr << errmsg << std::endl;

    return EXIT_FAILURE;

  }

 

  // Link the compiled program code into the runtime module.

  bool failed = llvm::Linker::LinkModules(

      rtlib, module_stab.module_ir.ptr(), llvm::Linker::PreserveSource, &errmsg

    );

  if(failed)

  {

    std::cerr << errmsg << std::endl;

    return EXIT_FAILURE;

  }

 

  std::cout << "Linking done..." << std::endl;

  rtlib->dump();

 

  // Run optimization passes.

  // std::vector<const char *> exportList;

  // llvm::PassManager Passes;

  // Passes.add(new llvm::DataLayout(rtlib));

  // Passes.add(llvm::createDemoteRegisterToMemoryPass());

  // Passes.add(llvm::createInternalizePass(exportList));

  // Passes.add(llvm::createScalarReplAggregatesPass());

  // Passes.add(llvm::createInstructionCombiningPass());

  // Passes.add(llvm::createGlobalOptimizerPass());

  // Passes.add(llvm::createFunctionInliningPass());

  // Passes.run(*rtlib);

 

  // Create the JIT

  llvm::InitializeNativeTarget();

  llvm::ExecutionEngine * jit = llvm::EngineBuilder(rtlib)

      .setErrorStr(&errmsg)

      .setEngineKind(llvm::EngineKind::JIT)

      .create();

  if(!jit)

  {

    std::cerr << "Failed to create JIT compiler: " << errmsg << std::endl;

    return EXIT_FAILURE;

  }

 

  // Execute the program.

  std::cout << "Begin Execution..." << std::endl;

  // rtlib->dump();

  void * main_fp = jit->getPointerToFunction(rtlib->getFunction("main"));

  int32_t (*target_program)() = (int32_t(*)())(intptr_t)(main_fp);

  std::cout << "Ready..." << std::endl;

  return target_program();

 

  #if 0

  // Write a bitcode file and interpret it.

  {

    std::string err;

    llvm::raw_fd_ostream fout("sprite-out.bc", err, llvm::raw_fd_ostream::F_Binary);

    llvm::WriteBitcodeToFile(module_stab.module_ir.ptr(), fout);

  }

  std::system("llvm-link-3.3 sprite-out.bc " SPRITE_LIBINSTALL "/sprite-rt.bc > tmp.bc");

  std::system("mv tmp.bc sprite-out.bc");

  int const status = std::system("lli-3.3 sprite-out.bc");

  return WEXITSTATUS(status);

  #endif

}

 

 

####################

 

 

define linkonce void <at> .step.myappend(%"struct.sprite::compiler::node"* %root_p) {

.entry:

  %0 = alloca %"struct.sprite::compiler::node"*

  %1 = alloca %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0

  %2 = load %"struct.sprite::compiler::node"** %0

  %3 = getelementptr %"struct.sprite::compiler::node"* %2, i32 0, i32 2

  %4 = load i8** %3

  %5 = bitcast i8* %4 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %5, %"struct.sprite::compiler::node"** %0

  br label %11

 

; <label>:6                                       ; preds = %11

  %7 = load %"struct.sprite::compiler::node"** %0

  %8 = getelementptr %"struct.sprite::compiler::node"* %7, i32 0, i32 2

  %9 = load i8** %8

  %10 = bitcast i8* %9 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %10, %"struct.sprite::compiler::node"** %0

  br label %11, !sprite.implied !0

 

; <label>:11                                      ; preds = %6, %.entry

  %12 = load %"struct.sprite::compiler::node"** %0

  %13 = getelementptr %"struct.sprite::compiler::node"* %12, i32 0, i32 1

  %14 = load i64* %13

  %15 = load i64* %13

  %16 = icmp eq i64 %15, -3

  br i1 %16, label %6, label %17

 

; <label>:17                                      ; preds = %11

  %18 = load %"struct.sprite::compiler::node"** %0

  store %"struct.sprite::compiler::node"* %18, %"struct.sprite::compiler::node"** %1

  %19 = getelementptr %"struct.sprite::compiler::node"* %18, i32 0, i32 1

  %20 = load i64* %19

  %21 = add i64 %20, 4

  %22 = getelementptr [6 x i8*]* <at> .jtable, i32 0, i64 %21

  %23 = load i8** %22

  indirectbr i8* %23, [label %24, label %26, label %36, label %38, label %44, label %66]

 

; <label>:24                                      ; preds = %26, %17

  %25 = call i32 (i8*, ...)* <at> printf(i8* getelementptr inbounds ([16 x i8]* <at> .str21, i32 0, i32 0))

  ret void, !case...FAIL !1

 

; <label>:26                                      ; preds = %26, %17

  %27 = load %"struct.sprite::compiler::node"** %1

  %28 = getelementptr %"struct.sprite::compiler::node"* %27, i32 0, i32 2

  %29 = load i8** %28

  %30 = bitcast i8* %29 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %30, %"struct.sprite::compiler::node"** %1

  %31 = getelementptr %"struct.sprite::compiler::node"* %30, i32 0, i32 1

  %32 = load i64* %31

  %33 = add i64 %32, 4

  %34 = getelementptr [6 x i8*]* <at> .jtable, i32 0, i64 %33

  %35 = load i8** %34

  indirectbr i8* %35, [label %24, label %26, label %36, label %38, label %44, label %66]

 

; <label>:36                                      ; preds = %26, %17

  %37 = call i32 (i8*, ...)* <at> printf(i8* getelementptr inbounds ([18 x i8]* <at> .str22, i32 0, i32 0))

  ret void, !case...CHOICE !1

 

; <label>:38                                      ; preds = %26, %17

  %39 = load %"struct.sprite::compiler::node"** %1

  %40 = getelementptr %"struct.sprite::compiler::node"* %39, i32 0, i32 0

  %41 = load %"struct.sprite::compiler::vtable"** %40

  %42 = getelementptr %"struct.sprite::compiler::vtable"* %41, i32 0, i32 4

  %43 = load void (%"struct.sprite::compiler::node"*)** %42

  tail call void %43(%"struct.sprite::compiler::node"* %39)

  ret void

 

; <label>:44                                      ; preds = %26, %17

  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0

  %45 = load %"struct.sprite::compiler::node"** %0

  %46 = getelementptr %"struct.sprite::compiler::node"* %45, i32 0, i32 3

  %47 = load i8** %46

  %48 = bitcast i8* %47 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %48, %"struct.sprite::compiler::node"** %0

  br label %54

 

; <label>:49                                      ; preds = %54

  %50 = load %"struct.sprite::compiler::node"** %0

  %51 = getelementptr %"struct.sprite::compiler::node"* %50, i32 0, i32 2

  %52 = load i8** %51

  %53 = bitcast i8* %52 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %53, %"struct.sprite::compiler::node"** %0

  br label %54, !sprite.implied !0

 

; <label>:54                                      ; preds = %49, %44

  %55 = load %"struct.sprite::compiler::node"** %0

  %56 = getelementptr %"struct.sprite::compiler::node"* %55, i32 0, i32 1

  %57 = load i64* %56

  %58 = load i64* %56

  %59 = icmp eq i64 %58, -3

  br i1 %59, label %49, label %60

 

; <label>:60                                      ; preds = %54

  %61 = load %"struct.sprite::compiler::node"** %0

  %62 = bitcast %"struct.sprite::compiler::node"* %61 to i8*

  %63 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 0

  store %"struct.sprite::compiler::vtable"* <at> .fwd.vt, %"struct.sprite::compiler::vtable"** %63

  %64 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 1

  store i64 -3, i64* %64

  %65 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 2

  store i8* %62, i8** %65

  ret void

 

; <label>:66                                      ; preds = %26, %17

  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0

  %67 = load %"struct.sprite::compiler::node"** %0

  %68 = getelementptr %"struct.sprite::compiler::node"* %67, i32 0, i32 2

  %69 = load i8** %68

  %70 = bitcast i8* %69 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %70, %"struct.sprite::compiler::node"** %0

  br label %76

 

; <label>:71                                      ; preds = %76

  %72 = load %"struct.sprite::compiler::node"** %0

  %73 = getelementptr %"struct.sprite::compiler::node"* %72, i32 0, i32 2

  %74 = load i8** %73

  %75 = bitcast i8* %74 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %75, %"struct.sprite::compiler::node"** %0

  br label %76, !sprite.implied !0

 

; <label>:76                                      ; preds = %71, %66

  %77 = load %"struct.sprite::compiler::node"** %0

  %78 = getelementptr %"struct.sprite::compiler::node"* %77, i32 0, i32 1

  %79 = load i64* %78

  %80 = load i64* %78

  %81 = icmp eq i64 %80, -3

  br i1 %81, label %71, label %82

 

; <label>:82                                      ; preds = %76

  %83 = load %"struct.sprite::compiler::node"** %0

  %84 = getelementptr %"struct.sprite::compiler::node"* %83, i32 0, i32 2

  %85 = load i8** %84

  %86 = bitcast i8* %85 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %86, %"struct.sprite::compiler::node"** %0

  br label %92

 

; <label>:87                                      ; preds = %92

  %88 = load %"struct.sprite::compiler::node"** %0

  %89 = getelementptr %"struct.sprite::compiler::node"* %88, i32 0, i32 2

  %90 = load i8** %89

  %91 = bitcast i8* %90 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %91, %"struct.sprite::compiler::node"** %0

  br label %92, !sprite.implied !0

 

; <label>:92                                      ; preds = %87, %82

  %93 = load %"struct.sprite::compiler::node"** %0

  %94 = getelementptr %"struct.sprite::compiler::node"* %93, i32 0, i32 1

  %95 = load i64* %94

  %96 = load i64* %94

  %97 = icmp eq i64 %96, -3

  br i1 %97, label %87, label %98

 

; <label>:98                                      ; preds = %92

  %99 = load %"struct.sprite::compiler::node"** %0

  %100 = bitcast %"struct.sprite::compiler::node"* %99 to i8*

  %101 = call i8* <at> malloc(i64 32)

  %102 = bitcast i8* %101 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0

  %103 = load %"struct.sprite::compiler::node"** %0

  %104 = getelementptr %"struct.sprite::compiler::node"* %103, i32 0, i32 2

  %105 = load i8** %104

  %106 = bitcast i8* %105 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %106, %"struct.sprite::compiler::node"** %0

  br label %112

 

; <label>:107                                     ; preds = %112

  %108 = load %"struct.sprite::compiler::node"** %0

  %109 = getelementptr %"struct.sprite::compiler::node"* %108, i32 0, i32 2

  %110 = load i8** %109

  %111 = bitcast i8* %110 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %111, %"struct.sprite::compiler::node"** %0

  br label %112, !sprite.implied !0

 

; <label>:112                                     ; preds = %107, %98

  %113 = load %"struct.sprite::compiler::node"** %0

  %114 = getelementptr %"struct.sprite::compiler::node"* %113, i32 0, i32 1

  %115 = load i64* %114

  %116 = load i64* %114

  %117 = icmp eq i64 %116, -3

  br i1 %117, label %107, label %118

 

; <label>:118                                     ; preds = %112

  %119 = load %"struct.sprite::compiler::node"** %0

  %120 = getelementptr %"struct.sprite::compiler::node"* %119, i32 0, i32 3

  %121 = load i8** %120

  %122 = bitcast i8* %121 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %122, %"struct.sprite::compiler::node"** %0

  br label %128

 

; <label>:123                                     ; preds = %128

  %124 = load %"struct.sprite::compiler::node"** %0

  %125 = getelementptr %"struct.sprite::compiler::node"* %124, i32 0, i32 2

  %126 = load i8** %125

  %127 = bitcast i8* %126 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %127, %"struct.sprite::compiler::node"** %0

  br label %128, !sprite.implied !0

 

; <label>:128                                     ; preds = %123, %118

  %129 = load %"struct.sprite::compiler::node"** %0

  %130 = getelementptr %"struct.sprite::compiler::node"* %129, i32 0, i32 1

  %131 = load i64* %130

  %132 = load i64* %130

  %133 = icmp eq i64 %132, -3

  br i1 %133, label %123, label %134

 

; <label>:134                                     ; preds = %128

  %135 = load %"struct.sprite::compiler::node"** %0

  %136 = bitcast %"struct.sprite::compiler::node"* %135 to i8*

  store %"struct.sprite::compiler::node"* %root_p, %"struct.sprite::compiler::node"** %0

  %137 = load %"struct.sprite::compiler::node"** %0

  %138 = getelementptr %"struct.sprite::compiler::node"* %137, i32 0, i32 3

  %139 = load i8** %138

  %140 = bitcast i8* %139 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %140, %"struct.sprite::compiler::node"** %0

  br label %146

 

; <label>:141                                     ; preds = %146

  %142 = load %"struct.sprite::compiler::node"** %0

  %143 = getelementptr %"struct.sprite::compiler::node"* %142, i32 0, i32 2

  %144 = load i8** %143

  %145 = bitcast i8* %144 to %"struct.sprite::compiler::node"*

  store %"struct.sprite::compiler::node"* %145, %"struct.sprite::compiler::node"** %0

  br label %146, !sprite.implied !0

 

; <label>:146                                     ; preds = %141, %134

  %147 = load %"struct.sprite::compiler::node"** %0

  %148 = getelementptr %"struct.sprite::compiler::node"* %147, i32 0, i32 1

  %149 = load i64* %148

  %150 = load i64* %148

  %151 = icmp eq i64 %150, -3

  br i1 %151, label %141, label %152

 

; <label>:152                                     ; preds = %146

  %153 = load %"struct.sprite::compiler::node"** %0

  %154 = bitcast %"struct.sprite::compiler::node"* %153 to i8*

  %155 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 0

  store %"struct.sprite::compiler::vtable"* <at> .vtable.for.myappend, %"struct.sprite::compiler::vtable"** %155

  %156 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 1

  store i64 -1, i64* %156

  %157 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 2

  store i8* %136, i8** %157

  %158 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0, i32 3

  store i8* %154, i8** %158

  %159 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 0

  store %"struct.sprite::compiler::vtable"* <at> .vt.CTOR.MyCons, %"struct.sprite::compiler::vtable"** %159

  %160 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 1

  store i64 1, i64* %160

  %161 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 2

  store i8* %100, i8** %161

  %162 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32 0, i32 3

  store i8* %101, i8** %162

  ret void

}

 

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Manish Gupta | 1 Sep 22:50 2014

Instrumenting Various Types Using Single Instrumentation Function

Hi All,


My instrumentation code needs to insert calls to transmit Value list. Each element in this list could be of different type. The list is sent to instrumenting function say void recordVarInputValues(int num, ...) . So, I have created a Union type in Tracing.cpp, which I link with my benchmark module at compile time. These steps are similar to giri instrumentation https://github.com/liuml07/giri

union NumericType
{
    int         iValue;
    long        lValue;  
    double      dValue;  
     ...
};

Now, I would like to convert all the llvm Values, required by recordVarInputValues function, to be of NumericType. So that a variable length list of NumerricType values can be passed to my instrumentation function. This way I will not have to create different instrumentation functions for different data types. 

Can I cast say i32 value to NumericType value in my instrumentation code, without inserting additional instructions in my benchmark code. I tried inserting bitcast instructions and it doesn't work for me...

if(!CastInst::isCastable(Lvals[j]->getType(), UnionVar->getType())){
      errs()<<"CAST TO NumericType NOT POSSIBLE\n";
      exit(0);
    }      
    CastInst *I = CastInst::CreateZExtOrBitCast(Lvals[j], UnionVar->getType(), "", F);
 

Is this even possible or some other method will be better? 

Thanks!
Manish
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Gaël Thomas | 1 Sep 21:34 2014
Picon

VMKit is retired (but you can help if you want!)

Hi all,

So, as explained in the LLVM weekly, the VMKit project is retired. It
was a very fun project, but we don't have any manpower to maintain the
code since one year. If someone is interested by restarting the
project, just send me an email, I can help to understand the
architecture of the project and how it works. I'm pretty sure that we
can also extract a Java to LLVM compiler easily (I know that some
people are interested by that).

And I want to thank all the LLVM team for their support during these
last ten (yes ten:)) years! Without their help, it would have been
impossible to develop VMKit.

See you and thank you!
Gaël

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Alex Bradbury | 1 Sep 19:46 2014

LLVM Weekly - #35, Sep 1st 2014

LLVM Weekly - #35, Sep 1st 2014
===============================

If you prefer, you can read a HTML version of this email at
<http://llvmweekly.org/issue/35>.

Welcome to the thirty-fifth issue of LLVM Weekly, a weekly newsletter
(published every Monday) covering developments in LLVM, Clang, and related
projects.LLVM Weekly is brought to you by [Alex
Bradbury](http://asbradbury.org).Subscribe to future issues at
<http://llvmweekly.org> and pass it on to anyone else you think may be
interested. Please send any tips or feedback to <asb <at> asbradbury.org>, or
 <at> llvmweekly or  <at> asbradbury on Twitter.

As I mentioned in a previous issue, I am involved in the
[lowRISC](http://lowrisc.org) projects to produce a fully open-source SoC.
Just a quick reminder that [we are
hiring](http://www.jobs.cam.ac.uk/job/4665/), and you have just over a week to
get your application in.

## News and articles from around the web

LLVM/Clang 3.5 is inching ever closer to release. The fourth and hopefully
final release candidate is [available for
testing](http://article.gmane.org/gmane.comp.compilers.llvm.devel/76370).

Quarks Lab have published a [preview of
SCAF](http://blog.quarkslab.com/scaf-source-code-analysis-framework-based-on-clang-pre-alpha-preview.html),
a Source Code Analysis Framework built on Clang. It promises a release soon.

The [VMKit project website](http://vmkit.llvm.org/) has this week been
[updated](http://reviews.llvm.org/rL216831) to mark the project as retired.
VMKit was a project to implement virtual machines such as a JVM on top of
LLVM. People interested in restarting the project are encouraged to get in
touch with Gaël Thomas.

AMD and Microsoft have [released a C++ AMP compiler targeting version 1.2 of
the specification](http://sdtimes.com/amd-announces-heterogeneous-c-amp-language-developers/).
The C++ AMP (Accelerated Massive Parallelism) compiler is of course based on
LLVM and Clang, and can be [found
here](https://bitbucket.org/multicoreware/cppamp-driver-ng/wiki/Home).

## On the mailing lists

* Manuel Klimek has provided a [quick run-down of the state of his work on
Clang C++ refactoring
tools](http://article.gmane.org/gmane.comp.compilers.clang.devel/38657). He
reports there are a number of standalone, single-use refacotring tools but
more work needs to be done on generalising and integrating them. The plan is
to push more of these tools to tools-extra (where clang-rename lives), make
them integratable as a library, integrate them into libclang and then
integrate them into projects like [ycmd](https://github.com/Valloric/ycmd).

* Robin Morisset has been working on optimisations for lowering of atomics and
has [asked for input on a fence elimination
algorithm](http://article.gmane.org/gmane.comp.compilers.llvm.devel/76400)
he's been thinking about. He has outlined two possible implementation routes
he would like feedback on.

* A discussion about [improving
llvm-objdump](http://article.gmane.org/gmane.comp.compilers.llvm.devel/76278),
kicked off by Steve King, makes an interesting read. I'm looking forward to a
future with a more featureful llvm-objdump that prints symbols of branch
targets by default.

* David Blaikie has started a discussion about [supporting -gmlt in
LLVM/Clang](http://article.gmane.org/gmane.comp.compilers.llvm.devel/76341).
Vital to having any chance of understanding this thread is to know that gmlt
refers to debug info containing 'minimal line tables', a feature that [was
added to GCC a while
back](https://gcc.gnu.org/ml/gcc-patches/2011-04/msg02075.html).

* I linked last week to the mailing list thread on removing static
initializers for command line options and regrettably was unable to summarise
the extensive discussion. The bad news is discussion has continued at a rapid
pace, but thankfully Chandler Carruth has rather helpfully [sumarised the main
outcomes of the
discussion](http://article.gmane.org/gmane.comp.compilers.llvm.devel/76279).
It's also worth reading [this
thread](http://article.gmane.org/gmane.comp.compilers.llvm.devel/76382) for an
idea of what the new infrastructure might look like.

## LLVM commits

* The AArch64 backend learned about v4f16 and v8f16 operations,
[r216555](http://reviews.llvm.org/rL216555).

* The LLVM CMake build system now includes support for building with
UndefinedBehaviourSanitizer. [r216701](http://reviews.llvm.org/rL216701).

## Clang commits

* The `-fdevirtualize` and `-fdevirtualize-speculatively` flags are now
recognised (and ignored) for compatibility with GCC.
[r216477](http://reviews.llvm.org/rL216477).

* Some Google Summer of Code work has started to land. In particular, the
Clang static analyzer gained initial infrastructure to support for
synthesizing function implementations from external model files. See the
commit message for full details on the intent of this feature.
[r216550](http://reviews.llvm.org/rL216550).

* Support was added for capturing variable length arrays in C++11 lambda
expressions. [r216649](http://reviews.llvm.org/rL216649).

## Other project commits

* LLDB gained documentation on its internal register numbering scheme.
[r216372](http://reviews.llvm.org/rL216372).

* LLDB is making progress towards AArch64 support.
[r216736](http://reviews.llvm.org/rL216737).

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
charlessl | 1 Sep 13:38 2014
Picon

Re: [3.5 Release] Release Candidate 4 Now Available

Hello

i wrote an IR test file that runs 100% slower  when compiled with llc 3.5 RC4
the unitary test file is joined to bug description #20410

Regards

> > We had to roll a release candidate 4 for the 3.5 release. It’s up at the normal place:
> >
> >         http://llvm.org/pre-releases/3.5
> >
> > Please test it and report any major bugs you may find.
> >
> > Thanks!
> > -bw

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
sara elshobaky | 1 Sep 07:37 2014
Picon

Modify a module at runtime in MCJIT

Hello,

I’m using MCJIT to run some loops on my ARM processor.

I was trying to perform some runtime optimizations on some function, and this requires recompiling the function at runtime.

I know that this feature is not available yet in MCJIT , and to modify a function I have to create a new module with the newly optimized code.

My questions are:

-          The newly created module can be added to the same execution engine or I have to create a new one?

-          Is it possible to swap the execution from the running module to the new optimized one at runtime? If yes, how? If no, are there any further solutions?

 

Please advice

Sara

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Gmane