Reid Kleckner | 30 Oct 21:29 2014
Picon

RFC: Drop support running LLVM on Windows XP

I'd like to raise our baseline Windows system requirements to Vista, dropping support for running LLVM on Windows XP. Microsoft dropped support for XP half a year ago in April 2014.

Our current status is that we require VS 2012 to build LLVM, and VS 2012 only runs on Vista+, but it has the ability produce binaries that run on XP. During the C++11-pocalypse, users expressed interest in keeping this working. I'm proposing that we drop support for this.

Vista introduced a lot of handy system APIs that could significantly simplify LLVM's Support library. For example, I'd really like to use the blessed one-time initialization routines in this CL:

Vista also introduced a bunch of condition variable APIs that I know less about, but that's another reason we might want to raise our base requirement as people look into parallel LTO and codegen. It also seems likely that we will want to use some of the new C++11 library features that are only present in newer CRTs, which don't run on XP.

Please respond if you have any objections. If there are no strong objections, I think we can start using Vista+ APIs in a week or so. We can still change our minds and revert stuff before the release if users feel this is too short notice.
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Riyaz Puthiyapurayil | 30 Oct 20:14 2014

What is the solution for this error from clang?

/usr/include/setjmp.h:58:12: error: conflicting types for '__sigsetjmp'
extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROW;
                    ^
/usr/include/pthread.h:712:12: note: previous declaration is here
extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROW;
                    ^
1 error generated.

Don't include both standard files??

% uname -o -m -r
2.6.18-274.12.1.el5 x86_64 GNU/Linux
betulb | 30 Oct 19:28 2014

RFC: Indirect Call Target Profiling

Hi All,

We've been working on adding indirect call target profiling support to the
instrumented profiler for PGO purposes. I’d like to propose the following
design.

Goal: Our aim is to add instrumentation around indirect call sites, so
that the run-time can track the callee addresses and their access
frequencies. From the addresses we’d like to infer the callee names and
use it in optimizations to improve the performance of applications which
make heavy use of indirect calls. Spec is a candidate benchmark that gives
us applications both written in C and C++ and makes use of indirect calls.
Spec can prove the effectiveness of optimizations making use of this
additional data.

Design:
To determine the function names from the profiled target addresses, we've
extended the data variable that is built by build_data_var() in
CodeGenPGO.cpp (abbr. PFDV: Per Function Data Variable) to save the
function addresses. PFDV is communicated to the run-time during function
registration and outputted in the raw profile data file. This data
structure is also extended to contain the number of indirect call sites
for each function.

To help communicate the target addresses to run-time, we insert a call to
a run-time routine before each indirect call site in clang. Something
like:

void instrument_indirect_call_site(uint8_t *TargetAddress, void *Data,
uint32_t CounterIndex);

This run-time function takes in the target address, the index/id of the
indirect call site and the pointer to the profile data variable of the
caller (i.e. PFDV). The runtime routine checks if the target address has
been seen before for the indirect call site index/id or not. If not, then
an entry is added into an internal data structure. If yes, the counter
associated with the target address is incremented by 1. This counter
records the number of times the target address is called.

Raw profile data file stores the target addresses and the number of times
any target address is taken per each call site index. llvm-profdata reads
the function addresses from the raw profile data file, then compares them
against the target addresses from the same file. Each match helps identify
the function names for the recorded addresses.

llvm-profdata processed files contain the target function names. In case
no function matches the target address then the target address is
converted to string and stored in that format in the “indexed” data files.
On the PGO path, clang consumes the returned indirect target data and
attaches the following metadata at the indirect call sites.

!33 = metadata !{metadata !"indirect_call_targets", i64
<total_exec_count>, metadata !"target_fn1”, i64 <target_fn1_count>,
metadata !"target_fn2”, i64 <target_fn2_count>, ….}

Only the top most called N function names are recorded at each indirect
call site. “indirect_call_targets” is the string literal identifying the
fields of this metadata. <total_exec_count> is a 64 bit value for the
total number of times the indirect call is executed followed by the
function names and execution counts of each target.

We're working on collecting further data points on the overhead of this
additional instrumentation on the original profiler. Looking forward to
hearing your comments.

Thanks,
-Betul Buyukkurt

Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Colin LeMahieu | 30 Oct 16:41 2014

ELF section load address

We had a need for calculating an ELF section load address, essentially the
LMA address printed out from GNU objdump with the –h option:

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .start        00003dc0  00000000  00000000  00001000  2**6

It looks like GNU binutils calculates this by applying the delta between the
vaddr and paddr of the section's enclosing segment.

I implemented this inside llvm-readobj:

  Section {
    Index: 30
    Name: .strtab (9)
    Type: SHT_STRTAB (0x3)
    Flags [ (0x0)
    ]
    Address: 0x0
    Load Address: 0x0
    Offset: 0x64FF88
    Size: 2689979
    Link: 0
    Info: 0
    AddressAlignment: 1
    EntrySize: 0
  }

Is there interest in this being upstreamed?  It's a small patch.

Is this the best place to put this information inside of llvm-readobj and
underneath the 'Address:' line.  If there's a better place let me know.

Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, 
a Linux Foundation Collaborative Project
Kenneth Camann | 30 Oct 02:54 2014
Picon

Runtime introspection of "Release Mode" programs using LLVM or LLDB

Hi everyone,

I'm working on a library for runtime introspection of C++ programs, for example, getting stack traces, decorating logs with source file information, etc. It currently uses LLVMObject and LLVMDebugInfo.

There's a feature I want to add, but it requires that I understand where on the stack local variables are located.

For this to work on x86-64, I would need to do whole "virtual unwinding" thing, i.e., create a library that can understand the DWARF call frame information. This is something that I do not want to do myself, because I would never have the resources to maintain it. LLVM and or LLDB must have code for doing this already though.

In fact, since this sort of dynamic inspection is kind of like debugging, I originally thought LLDB would work better in the first place. I actually tried early on to use LLDB, but I gave up quickly. The API seems to be designed so that you must always attach one process to another, using an operating system facility like ptrace.

That is not really compatible with the idea of the program inspecting _itself_, although I think there is definitely a place for that, e.g. portable stack traces, source info without the need for __FILE__ and __LINE__ boilerplate, etc.

Does LLDB support anything like this, and I just didn't find it? Or going another route, is there any plan for the DWARF classes in LLVMDebugInfo to ever support APIs for understanding the call frame info?

If neither, any advice on what I should do?

Thanks!
Ken
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
William Swartzendruber | 30 Oct 00:09 2014
Picon

Status of HSA in LLVM 3.6

Hello all,

I just got myself an AMD Kaveri chip to get into HSA programming.  I see there is a fork of LLVM 3.2 for this, but have those changes been merged back in yet?

I don't mind writing HSAIL by hand.  Can I at least assemble and link?

Thanks,
-William
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Xiaoguang Wang | 29 Oct 22:24 2014
Picon

Emit a jump instruction to a place inside basicblock

Hi all,

I'm a beginner in LLVM. Currently, I want to implement a pass that generates a jump table. The entry in that table is a jump to some place (may be an instruction) in a basic block.

I'm reading the JumpTable code in llvm 3.5, there is a table which contains jump entries to functions. In AsmPrinter::doFinalization function from file lib/CodeGen/AsmPrinter/AsmPrinter.cpp, it gets a MCSymbolRefExpr from the function symbol.

While my question is, is there a way to insert jump to place inside a basic block?

Thanks!

Xiaoguang
_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Ramkumar Ramachandra | 29 Oct 20:21 2014
Picon

[PATCH v2] LangRef: clarify that va_arg doesn't work on x86_64

Since x86_64 is easily the most popular platform, it deserves special
mention. varargs on x86_64 probably requires a separate page.

Cc: Tim Northover <t.p.northover <at> gmail.com>
Cc: Reid Kleckner <rnk <at> google.com>
Signed-off-by: Ramkumar Ramachandra <artagnon <at> gmail.com>
---
 docs/LangRef.rst | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index ddef803..b288f9b 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
 <at>  <at>  -6695,7 +6695,8  <at>  <at>  Overview:

 The '``va_arg``' instruction is used to access arguments passed through
 the "variable argument" area of a function call. It is used to implement
-the ``va_arg`` macro in C.
+the ``va_arg`` macro in C. Note that ``va_arg`` does not work on
+platforms that have a non-builtin ``va_list`` type, like x86_64.

 Arguments:
 """"""""""
 <at>  <at>  -6879,8 +6880,10  <at>  <at>  value type "``va_list``". The LLVM assembly language reference manual
 does not define what this type is, so all transformations should be
 prepared to handle these functions regardless of the type used.

-This example shows how the :ref:`va_arg <i_va_arg>` instruction and the
-variable argument handling intrinsic functions are used.
+This example shows how the :ref:`va_arg <i_va_arg>` instruction and
+the variable argument handling intrinsic functions are used. Note that
+this is for platforms where ``va_list`` is an ``i8**``, most notably
+not x86_64.

 .. code-block:: llvm

--

-- 
1.9.3 (Apple Git-50)
Jun Koi | 29 Oct 15:46 2014
Picon

Mips's MicroMips ??

Hi,

We have this line in micromips-16-bit-instructions.s

    # CHECK-EB: addu16  $6, $17, $4     # encoding: [0x07,0x42]

However, when I check this with llvm-mc, like below, I dont get back the assembly.
This is against the latest LLVM code. What is wrong here?

Thanks,
Jun


$ echo "0x07,0x42"|./Release+Asserts/bin/llvm-mc -disassemble -triple=mips -show-encoding -mattr=micromips
    .text
<stdin>:1:1: warning: invalid instruction encoding
0x07,0x42
^
<stdin>:1:6: warning: invalid instruction encoding
0x07,0x42

_______________________________________________
LLVM Developers mailing list
LLVMdev <at> cs.uiuc.edu         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Ramkumar Ramachandra | 29 Oct 02:32 2014
Picon

[PATCH] LangRef: va_arg doesn't work on X86_64; update example

Provide a full-fledged example of working variable arguments on X86_64,
since it's easily the most popular platform.

Cc: Reid Kleckner <rnk <at> google.com>
Signed-off-by: Ramkumar Ramachandra <artagnon <at> gmail.com>
---
 docs/LangRef.rst | 44 ++++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index ddef803..f429062 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
 <at>  <at>  -6695,7 +6695,8  <at>  <at>  Overview:

 The '``va_arg``' instruction is used to access arguments passed through
 the "variable argument" area of a function call. It is used to implement
-the ``va_arg`` macro in C.
+the ``va_arg`` macro in C. Note that ``va_arg`` does not work on
+platforms that have a non-builtin ``va_list`` type, like x86_64.

 Arguments:
 """"""""""
 <at>  <at>  -6879,29 +6880,44  <at>  <at>  value type "``va_list``". The LLVM assembly language reference manual
 does not define what this type is, so all transformations should be
 prepared to handle these functions regardless of the type used.

-This example shows how the :ref:`va_arg <i_va_arg>` instruction and the
-variable argument handling intrinsic functions are used.
+This example shows how the variable argument handling is done on
+x86_64. The complexity arises from the fact that ``va_arg`` does not
+work on this type of ``va_list``.

 .. code-block:: llvm

+    %struct.__va_list_tag = type { i32, i32, i8*, i8* }
+
     define i32  <at> test(i32 %X, ...) {
       ; Initialize variable argument processing
-      %ap = alloca i8*
-      %ap2 = bitcast i8** %ap to i8*
+      %ap = alloca %struct.__va_list_tag
+      %ap2 = bitcast %struct.__va_list_tag* %ap to i8*
+      %retptr = alloca i32
       call void  <at> llvm.va_start(i8* %ap2)

       ; Read a single integer argument
-      %tmp = va_arg i8** %ap, i32
-
-      ; Demonstrate usage of llvm.va_copy and llvm.va_end
-      %aq = alloca i8*
-      %aq2 = bitcast i8** %aq to i8*
-      call void  <at> llvm.va_copy(i8* %aq2, i8* %ap2)
-      call void  <at> llvm.va_end(i8* %aq2)
-
+      %idxptr = getelementptr inbounds %struct.__va_list_tag* %ap, i32 0, i32 0
+      %idx = load i32* %idxptr
+      %tmp = getelementptr inbounds %struct.__va_list_tag* %ap, i32 0, i32 3
+      %extract = load i8** %tmp
+      %rawel = getelementptr i8* %extract, i32 %idx
+      %elptr = bitcast i8* %rawel to i32*
+      %newidx = add i32 %idx, 8
+      store i32 %idx, i32* %idxptr
+    
+      ; Store that argument in el
+      %el = load i32* %elptr
+      store i32 %el, i32* %retptr
+      %ret = load i32* %retptr
+    
       ; Stop processing of arguments.
       call void  <at> llvm.va_end(i8* %ap2)
-      ret i32 %tmp
+      ret i32 %ret
+    }
+
+    define i32  <at> main() {
+      %call = call i32 (i32, ...)*  <at> test(i32 1, i32 3)
+      ret i32 %call
     }

     declare void  <at> llvm.va_start(i8*)
--

-- 
1.9.3 (Apple Git-50)
Rinaldini Julien | 28 Oct 21:55 2014
Picon

Problem in X86 backend (again)

Hi,

I'm still having problems implementing my custom inserter in the X86 backend.

I found a solution to my last problem
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-October/078296.html), by using a virtual register.

The binary works when it's compiled in -O0, but not in -O1,-O2,...

I really can't figure what I'm doing wrong... Any idea?

Here is the code of my custom inserter... The goal of this code is to erase the stack in the epilogue of a function:

MachineBasicBlock *
X86TargetLowering::EmitBURNSTACKWithCustomInserter(
MachineInstr *MI,
MachineBasicBlock *MBB) const {
MBB->getParent()->dump();
DebugLoc db = MI->getDebugLoc();
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
const BasicBlock *LLVM_BB = MBB->getBasicBlock();
MachineFunction *F = MBB->getParent();
// Create all the basicblocks
MachineBasicBlock *MBB_cond = F->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *MBB_erase = F->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *MBB_end = F->CreateMachineBasicBlock(LLVM_BB);
// Insert the new basicblocks
F->insert(MBB, MBB_cond);
F->insert(MBB, MBB_erase);
F->insert(MBB, MBB_end);
// Split the last MBB in two
MBB_end->splice(MBB_end->begin(), MBB, next(MachineBasicBlock::iterator(MI)), MBB->end());
MBB_end->transferSuccessorsAndUpdatePHIs(MBB);
// Move MBB at the right place
MBB_end->moveAfter(MBB);
MBB_erase->moveAfter(MBB);
MBB_cond->moveAfter(MBB);
// Set the new successors
MBB->addSuccessor(MBB_cond);
MBB_erase->addSuccessor(MBB_cond);
MBB_cond->addSuccessor(MBB_end);
MBB_cond->addSuccessor(MBB_erase);
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
const TargetRegisterClass *AddrRegClass = getRegClassFor(MVT::i64);
unsigned reg = MRI.createVirtualRegister(AddrRegClass);
// Set the indice
BuildMI(*MBB, MI, db, TII->get(X86::MOV64rr)).addReg(reg).addReg(X86::RSP);
// Create the for loop condition
BuildMI(*MBB_cond, MBB_cond->end(), db, TII->get(X86::CMP64rr)).addReg(reg).addReg(X86::RBP);
BuildMI(*MBB_cond, MBB_cond->end(), db, TII->get(X86::JE_4)).addMBB(MBB_end);
// Update phi node
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::PHI), reg).addReg(reg).addMBB(MBB).addReg(reg).addMBB(MBB_erase);
// Erase content of stack
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::MOV32mi))
.addReg(reg).addImm(1).addReg(0).addImm(0).addReg(0)
.addImm(0);
// Increment loop variable and jmp
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::ADD64ri32), reg).addReg(reg).addImm(8);
BuildMI(*MBB_erase, MBB_erase->end(), db, TII->get(X86::JMP_4)).addMBB(MBB_cond);
// Erase intrinsic
MI->eraseFromParent();
MBB->getParent()->dump();
return MBB_cond;
}

Here is the dump of the original function before my custom inserter (it's basically a main function with a
printf and a return inside it):

# Machine code for function main: SSA
BB#0: derived from LLVM BB %entry
ADJCALLSTACKDOWN64 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg2<def> = MOV32ri64 <ga: <at> str>; GR32:%vreg2
%vreg3<def> = SUBREG_TO_REG 0, %vreg2<kill>, 4; GR64:%vreg3 GR32:%vreg2
%RDI<def> = COPY %vreg3; GR64:%vreg3
CALL64pcrel32 <ga: <at> puts>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %EAX<imp-def>
ADJCALLSTACKUP64 0, 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg4<def> = COPY %EAX; GR32:%vreg4
BURNSTACK %EFLAGS<imp-def,dead>
%vreg5<def> = MOV32r0 %EFLAGS<imp-def,dead>; GR32:%vreg5
%EAX<def> = COPY %vreg5; GR32:%vreg5
RETQ %EAX
# End machine code for function main.

Here is the dump after my custom inserter (with the stacktrace):

# Machine code for function main: SSA
BB#0: derived from LLVM BB %entry
ADJCALLSTACKDOWN64 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg2<def> = MOV32ri64 <ga: <at> str>; GR32:%vreg2
%vreg3<def> = SUBREG_TO_REG 0, %vreg2<kill>, 4; GR64:%vreg3 GR32:%vreg2
%RDI<def> = COPY %vreg3; GR64:%vreg3
CALL64pcrel32 <ga: <at> puts>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, %EAX<imp-def>
ADJCALLSTACKUP64 0, 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>, %RSP<imp-use>
%vreg4<def> = COPY %EAX; GR32:%vreg4
MOV64rr %vreg6, %RSP; GR64:%vreg6
Successors according to CFG: BB#1
BB#1: derived from LLVM BB %entry
Predecessors according to CFG: BB#0 BB#2
CMP64rr %vreg6, %RBP, %EFLAGS<imp-def>; GR64:%vreg6
JE_4 <BB#3>, %EFLAGS<imp-use>
Successors according to CFG: BB#3 BB#2
BB#2: derived from LLVM BB %entry
Predecessors according to CFG: BB#1
%vreg6<def> = PHI %vreg6, <BB#0>, %vreg6, <BB#2>; GR64:%vreg6
MOV32mi %vreg6, 1, %noreg, 0, %noreg, 0; GR64:%vreg6
%vreg6<def,tied1> = ADD64ri32 %vreg6<tied0>, 8, %EFLAGS<imp-def>; GR64:%vreg6
JMP_4 <BB#1>
Successors according to CFG: BB#1
BB#3: derived from LLVM BB %entry
Predecessors according to CFG: BB#1
%vreg5<def> = MOV32r0 %EFLAGS<imp-def,dead>; GR32:%vreg5
%EAX<def> = COPY %vreg5; GR32:%vreg5
RETQ %EAX
# End machine code for function main.
clang: /home/pyknite/work/ollvm/obfuscator-llvm/lib/CodeGen/MachineRegisterInfo.cpp:305:
llvm::MachineInstr *llvm::MachineRegisterInfo::getVRegDef(unsigned int) const: Assertion
`(I.atEnd() || std::next(I) == def_instr_end()) && "getVRegDef assumes a single definition or no
definition"' failed.
0 clang 0x00000000027c3645 llvm::sys::PrintStackTrace(_IO_FILE*) + 37
1 clang 0x00000000027c3e33
2 libpthread.so.0 0x00007fba6de1b200
3 libc.so.6 0x00007fba6cbcc967 gsignal + 55
4 libc.so.6 0x00007fba6cbcdd3a abort + 362
5 libc.so.6 0x00007fba6cbc58ad
6 libc.so.6 0x00007fba6cbc5962
7 clang 0x00000000021a6a06 llvm::MachineRegisterInfo::getVRegDef(unsigned int) const + 118
8 clang 0x0000000002194ddc
9 clang 0x0000000002191986
10 clang 0x000000000218396c llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 124
11 clang 0x00000000026f8f3b llvm::FPPassManager::runOnFunction(llvm::Function&) + 539
12 clang 0x00000000026f91ab llvm::FPPassManager::runOnModule(llvm::Module&) + 43
13 clang 0x00000000026f9727 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 967
14 clang 0x00000000008e461d clang::EmitBackendOutput(clang::DiagnosticsEngine&,
clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&,
llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 7293
15 clang 0x00000000008e1b4a
16 clang 0x0000000000ace263 clang::ParseAST(clang::Sema&, bool, bool) + 467
17 clang 0x0000000000700cde clang::FrontendAction::Execute() + 62
18 clang 0x00000000006d5e13 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 851
19 clang 0x00000000006b7e60 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 3104
20 clang 0x00000000006aebe9 cc1_main(char const**, char const**, char const*, void*) + 665
21 clang 0x00000000006b538a main + 8154
22 libc.so.6 0x00007fba6cbb9040 __libc_start_main + 240
23 clang 0x00000000006ae87d

Cheers

Gmane