2017-02-27 23:45:06 +01:00
|
|
|
//===- FastISel.cpp - Implementation of the FastISel class ----------------===//
|
2008-08-13 22:19:35 +02:00
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2008-08-13 22:19:35 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains the implementation of the FastISel class.
|
|
|
|
//
|
2008-09-30 22:48:29 +02:00
|
|
|
// "Fast" instruction selection is designed to emit very poor code quickly.
|
|
|
|
// Also, it is not designed to be able to do much lowering, so most illegal
|
2008-10-13 03:59:13 +02:00
|
|
|
// types (e.g. i64 on 32-bit targets) and operations are not supported. It is
|
|
|
|
// also not intended to be able to do much optimization, except in a few cases
|
|
|
|
// where doing optimizations reduces overall compile time. For example, folding
|
|
|
|
// constants into immediate fields is often done, because it's cheap and it
|
|
|
|
// reduces the number of instructions later phases have to examine.
|
2008-09-30 22:48:29 +02:00
|
|
|
//
|
|
|
|
// "Fast" instruction selection is able to fail gracefully and transfer
|
|
|
|
// control to the SelectionDAG selector for operations that it doesn't
|
2008-10-13 03:59:13 +02:00
|
|
|
// support. In many cases, this allows us to avoid duplicating a lot of
|
2008-09-30 22:48:29 +02:00
|
|
|
// the complicated lowering logic that SelectionDAG currently has.
|
|
|
|
//
|
|
|
|
// The intended use for "fast" instruction selection is "-O0" mode
|
|
|
|
// compilation, where the quality of the generated code is irrelevant when
|
2008-10-13 03:59:13 +02:00
|
|
|
// weighed against the speed at which the code can be generated. Also,
|
2008-09-30 22:48:29 +02:00
|
|
|
// at -O0, the LLVM optimizers are not running, and this makes the
|
|
|
|
// compile time of codegen a much higher portion of the overall compile
|
2008-10-13 03:59:13 +02:00
|
|
|
// time. Despite its limitations, "fast" instruction selection is able to
|
2008-09-30 22:48:29 +02:00
|
|
|
// handle enough code on its own to provide noticeable overall speedups
|
|
|
|
// in -O0 compiles.
|
|
|
|
//
|
|
|
|
// Basic operations are supported in a target-independent way, by reading
|
|
|
|
// the same instruction descriptions that the SelectionDAG selector reads,
|
|
|
|
// and identifying simple arithmetic operations that can be directly selected
|
2008-10-13 03:59:13 +02:00
|
|
|
// from simple operators. More complicated operations currently require
|
2008-09-30 22:48:29 +02:00
|
|
|
// target-specific code.
|
|
|
|
//
|
2008-08-13 22:19:35 +02:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-06-06 13:49:48 +02:00
|
|
|
#include "llvm/CodeGen/FastISel.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/ADT/APFloat.h"
|
2017-03-19 17:50:25 +01:00
|
|
|
#include "llvm/ADT/APSInt.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2013-06-16 22:34:15 +02:00
|
|
|
#include "llvm/ADT/Optional.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
|
|
#include "llvm/ADT/SmallString.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2012-12-03 17:50:05 +01:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
2014-06-13 02:45:11 +02:00
|
|
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
2015-01-15 03:16:27 +01:00
|
|
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
2012-12-03 17:50:05 +01:00
|
|
|
#include "llvm/CodeGen/Analysis.h"
|
2010-07-07 18:01:37 +02:00
|
|
|
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/CodeGen/ISDOpcodes.h"
|
|
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
2014-06-12 05:29:26 +02:00
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
2008-08-13 22:19:35 +02:00
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/CodeGen/MachineMemOperand.h"
|
2008-09-25 19:05:24 +02:00
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/CodeGen/MachineOperand.h"
|
2008-08-13 22:19:35 +02:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2014-06-12 05:29:26 +02:00
|
|
|
#include "llvm/CodeGen/StackMaps.h"
|
2017-11-08 02:01:31 +01:00
|
|
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
2017-11-17 02:07:10 +01:00
|
|
|
#include "llvm/CodeGen/TargetLowering.h"
|
|
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
2018-03-29 19:21:10 +02:00
|
|
|
#include "llvm/CodeGen/ValueTypes.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/IR/Argument.h"
|
|
|
|
#include "llvm/IR/Attributes.h"
|
|
|
|
#include "llvm/IR/BasicBlock.h"
|
|
|
|
#include "llvm/IR/CallingConv.h"
|
|
|
|
#include "llvm/IR/Constant.h"
|
|
|
|
#include "llvm/IR/Constants.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
2014-03-06 01:46:21 +01:00
|
|
|
#include "llvm/IR/DebugInfo.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/IR/DebugLoc.h"
|
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Function.h"
|
2016-01-20 01:26:52 +01:00
|
|
|
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/IR/GlobalValue.h"
|
|
|
|
#include "llvm/IR/InlineAsm.h"
|
|
|
|
#include "llvm/IR/InstrTypes.h"
|
|
|
|
#include "llvm/IR/Instruction.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "llvm/IR/IntrinsicInst.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/IR/LLVMContext.h"
|
2015-06-23 14:21:54 +02:00
|
|
|
#include "llvm/IR/Mangler.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/IR/Metadata.h"
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Operator.h"
|
2018-10-25 20:09:33 +02:00
|
|
|
#include "llvm/IR/PatternMatch.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/IR/Type.h"
|
|
|
|
#include "llvm/IR/User.h"
|
|
|
|
#include "llvm/IR/Value.h"
|
|
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
#include "llvm/MC/MCInstrDesc.h"
|
|
|
|
#include "llvm/MC/MCRegisterInfo.h"
|
|
|
|
#include "llvm/Support/Casting.h"
|
2012-12-03 17:50:05 +01:00
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2018-03-24 00:58:25 +01:00
|
|
|
#include "llvm/Support/MachineValueType.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2015-03-23 20:32:43 +01:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2008-08-20 23:05:57 +02:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2017-02-27 23:45:06 +01:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <iterator>
|
|
|
|
#include <utility>
|
|
|
|
|
2008-08-13 22:19:35 +02:00
|
|
|
using namespace llvm;
|
2018-10-25 20:09:33 +02:00
|
|
|
using namespace PatternMatch;
|
2008-08-13 22:19:35 +02:00
|
|
|
|
2014-04-22 04:02:50 +02:00
|
|
|
#define DEBUG_TYPE "isel"
|
|
|
|
|
2011-11-28 20:59:09 +01:00
|
|
|
STATISTIC(NumFastIselSuccessIndependent, "Number of insts selected by "
|
2014-09-03 20:46:45 +02:00
|
|
|
"target-independent selector");
|
2011-11-28 20:59:09 +01:00
|
|
|
STATISTIC(NumFastIselSuccessTarget, "Number of insts selected by "
|
2014-09-03 20:46:45 +02:00
|
|
|
"target-specific selector");
|
2011-11-29 20:40:47 +01:00
|
|
|
STATISTIC(NumFastIselDead, "Number of dead insts removed on failure");
|
2011-11-16 22:05:28 +01:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
/// Set the current block to which generated machine instructions will be
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
/// appended.
|
2010-07-10 11:00:22 +02:00
|
|
|
void FastISel::startNewBlock() {
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
assert(LocalValueMap.empty() &&
|
|
|
|
"local values should be cleared after finishing a BB");
|
2010-07-10 11:00:22 +02:00
|
|
|
|
2013-07-04 06:53:49 +02:00
|
|
|
// Instructions are appended to FuncInfo.MBB. If the basic block already
|
2013-07-04 06:32:39 +02:00
|
|
|
// contains labels or copies, use the last instruction as the last local
|
|
|
|
// value.
|
2014-04-14 02:51:57 +02:00
|
|
|
EmitStartPt = nullptr;
|
2013-07-04 06:32:39 +02:00
|
|
|
if (!FuncInfo.MBB->empty())
|
|
|
|
EmitStartPt = &FuncInfo.MBB->back();
|
2011-08-19 00:06:10 +02:00
|
|
|
LastLocalValue = EmitStartPt;
|
|
|
|
}
|
|
|
|
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
void FastISel::finishBasicBlock() { flushLocalValueMap(); }
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
bool FastISel::lowerArguments() {
|
2013-02-11 02:27:15 +01:00
|
|
|
if (!FuncInfo.CanLowerReturn)
|
|
|
|
// Fallback to SDISel argument lowering code to deal with sret pointer
|
|
|
|
// parameter.
|
|
|
|
return false;
|
2013-07-08 02:37:03 +02:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
if (!fastLowerArguments())
|
2013-02-11 02:27:15 +01:00
|
|
|
return false;
|
|
|
|
|
2013-06-22 00:56:30 +02:00
|
|
|
// Enter arguments into ValueMap for uses in non-entry BBs.
|
2013-02-11 02:27:15 +01:00
|
|
|
for (Function::const_arg_iterator I = FuncInfo.Fn->arg_begin(),
|
2014-09-03 20:46:45 +02:00
|
|
|
E = FuncInfo.Fn->arg_end();
|
|
|
|
I != E; ++I) {
|
2020-04-08 16:57:11 +02:00
|
|
|
DenseMap<const Value *, Register>::iterator VI = LocalValueMap.find(&*I);
|
2013-06-22 00:56:30 +02:00
|
|
|
assert(VI != LocalValueMap.end() && "Missed an argument?");
|
2015-10-13 21:47:46 +02:00
|
|
|
FuncInfo.ValueMap[&*I] = VI->second;
|
2013-02-11 02:27:15 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
/// Return the defined register if this instruction defines exactly one
|
|
|
|
/// virtual register and uses no other virtual registers. Otherwise return 0.
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
static Register findLocalRegDef(MachineInstr &MI) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register RegDef;
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
for (const MachineOperand &MO : MI.operands()) {
|
|
|
|
if (!MO.isReg())
|
|
|
|
continue;
|
|
|
|
if (MO.isDef()) {
|
|
|
|
if (RegDef)
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
return Register();
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
RegDef = MO.getReg();
|
2020-04-08 16:57:11 +02:00
|
|
|
} else if (MO.getReg().isVirtual()) {
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
// This is another use of a vreg. Don't delete it.
|
2020-04-08 16:57:11 +02:00
|
|
|
return Register();
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return RegDef;
|
|
|
|
}
|
|
|
|
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
static bool isRegUsedByPhiNodes(Register DefReg,
|
|
|
|
FunctionLoweringInfo &FuncInfo) {
|
|
|
|
for (auto &P : FuncInfo.PHINodesToUpdate)
|
|
|
|
if (P.second == DefReg)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-08-19 00:06:10 +02:00
|
|
|
void FastISel::flushLocalValueMap() {
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
// If FastISel bails out, it could leave local value instructions behind
|
|
|
|
// that aren't used for anything. Detect and erase those.
|
|
|
|
if (LastLocalValue != EmitStartPt) {
|
|
|
|
// Save the first instruction after local values, for later.
|
|
|
|
MachineBasicBlock::iterator FirstNonValue(LastLocalValue);
|
|
|
|
++FirstNonValue;
|
|
|
|
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
MachineBasicBlock::reverse_iterator RE =
|
|
|
|
EmitStartPt ? MachineBasicBlock::reverse_iterator(EmitStartPt)
|
|
|
|
: FuncInfo.MBB->rend();
|
|
|
|
MachineBasicBlock::reverse_iterator RI(LastLocalValue);
|
|
|
|
for (; RI != RE;) {
|
|
|
|
MachineInstr &LocalMI = *RI;
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
// Increment before erasing what it points to.
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
++RI;
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
Register DefReg = findLocalRegDef(LocalMI);
|
|
|
|
if (!DefReg)
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
continue;
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
if (FuncInfo.RegsWithFixups.count(DefReg))
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
continue;
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
bool UsedByPHI = isRegUsedByPhiNodes(DefReg, FuncInfo);
|
|
|
|
if (!UsedByPHI && MRI.use_nodbg_empty(DefReg)) {
|
|
|
|
if (EmitStartPt == &LocalMI)
|
|
|
|
EmitStartPt = EmitStartPt->getPrevNode();
|
|
|
|
LLVM_DEBUG(dbgs() << "removing dead local value materialization"
|
|
|
|
<< LocalMI);
|
|
|
|
LocalMI.eraseFromParent();
|
|
|
|
}
|
|
|
|
}
|
2020-12-01 22:23:30 +01:00
|
|
|
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
if (FirstNonValue != FuncInfo.MBB->end()) {
|
|
|
|
// See if there are any local value instructions left. If so, we want to
|
|
|
|
// make sure the first one has a debug location; if it doesn't, use the
|
|
|
|
// first non-value instruction's debug location.
|
|
|
|
|
|
|
|
// If EmitStartPt is non-null, this block had copies at the top before
|
|
|
|
// FastISel started doing anything; it points to the last one, so the
|
|
|
|
// first local value instruction is the one after EmitStartPt.
|
|
|
|
// If EmitStartPt is null, the first local value instruction is at the
|
|
|
|
// top of the block.
|
|
|
|
MachineBasicBlock::iterator FirstLocalValue =
|
|
|
|
EmitStartPt ? ++MachineBasicBlock::iterator(EmitStartPt)
|
|
|
|
: FuncInfo.MBB->begin();
|
|
|
|
if (FirstLocalValue != FirstNonValue && !FirstLocalValue->getDebugLoc())
|
|
|
|
FirstLocalValue->setDebugLoc(FirstNonValue->getDebugLoc());
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-19 00:06:10 +02:00
|
|
|
LocalValueMap.clear();
|
|
|
|
LastLocalValue = EmitStartPt;
|
|
|
|
recomputeInsertPt();
|
2014-09-08 22:24:10 +02:00
|
|
|
SavedInsertPt = FuncInfo.InsertPt;
|
2020-12-01 22:23:30 +01:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::getRegForValue(const Value *V) {
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT RealVT = TLI.getValueType(DL, V->getType(), /*AllowUnknown=*/true);
|
2009-04-07 22:40:11 +02:00
|
|
|
// Don't handle non-simple values in FastISel.
|
|
|
|
if (!RealVT.isSimple())
|
2020-04-08 16:57:11 +02:00
|
|
|
return Register();
|
2008-09-10 23:01:08 +02:00
|
|
|
|
2008-12-08 08:57:47 +01:00
|
|
|
// Ignore illegal types. We must do this before looking up the value
|
|
|
|
// in ValueMap because Arguments are given virtual registers regardless
|
|
|
|
// of whether FastISel can handle them.
|
2009-08-11 22:47:22 +02:00
|
|
|
MVT VT = RealVT.getSimpleVT();
|
2008-09-10 23:01:08 +02:00
|
|
|
if (!TLI.isTypeLegal(VT)) {
|
2011-05-26 01:49:02 +02:00
|
|
|
// Handle integer promotions, though, because they're common and easy.
|
|
|
|
if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
|
2009-08-12 02:36:31 +02:00
|
|
|
VT = TLI.getTypeToTransformTo(V->getContext(), VT).getSimpleVT();
|
2008-09-10 23:01:08 +02:00
|
|
|
else
|
2020-04-08 16:57:11 +02:00
|
|
|
return Register();
|
2008-09-10 23:01:08 +02:00
|
|
|
}
|
|
|
|
|
2012-03-20 02:07:47 +01:00
|
|
|
// Look up the value to see if we already have a register for it.
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Reg = lookUpRegForValue(V);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Reg)
|
2008-12-08 08:57:47 +01:00
|
|
|
return Reg;
|
|
|
|
|
2010-05-06 02:02:14 +02:00
|
|
|
// In bottom-up mode, just create the virtual register which will be used
|
|
|
|
// to hold the value. It will be materialized later.
|
2010-07-10 11:00:22 +02:00
|
|
|
if (isa<Instruction>(V) &&
|
|
|
|
(!isa<AllocaInst>(V) ||
|
|
|
|
!FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(V))))
|
|
|
|
return FuncInfo.InitializeRegForValue(V);
|
|
|
|
|
2012-10-03 10:10:01 +02:00
|
|
|
SavePoint SaveInsertPt = enterLocalValueArea();
|
2010-07-10 11:00:22 +02:00
|
|
|
|
|
|
|
// Materialize the value in a register. Emit any instructions in the
|
|
|
|
// local value area.
|
|
|
|
Reg = materializeRegForValue(V, VT);
|
|
|
|
|
2012-10-03 10:10:01 +02:00
|
|
|
leaveLocalValueArea(SaveInsertPt);
|
2010-05-06 02:02:14 +02:00
|
|
|
|
2010-07-10 11:00:22 +02:00
|
|
|
return Reg;
|
2010-05-04 01:36:34 +02:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::materializeConstant(const Value *V, MVT VT) {
|
|
|
|
Register Reg;
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *CI = dyn_cast<ConstantInt>(V)) {
|
2008-09-20 00:16:54 +02:00
|
|
|
if (CI->getValue().getActiveBits() <= 64)
|
2014-09-03 22:56:59 +02:00
|
|
|
Reg = fastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
2014-08-19 21:05:24 +02:00
|
|
|
} else if (isa<AllocaInst>(V))
|
2014-09-03 22:56:52 +02:00
|
|
|
Reg = fastMaterializeAlloca(cast<AllocaInst>(V));
|
2014-08-19 21:05:24 +02:00
|
|
|
else if (isa<ConstantPointerNull>(V))
|
2008-10-08 00:03:27 +02:00
|
|
|
// Translate this as an integer zero so that it can be
|
|
|
|
// local-CSE'd with actual integer zeros.
|
2019-10-25 01:37:23 +02:00
|
|
|
Reg =
|
|
|
|
getRegForValue(Constant::getNullValue(DL.getIntPtrType(V->getType())));
|
2014-09-03 20:46:45 +02:00
|
|
|
else if (const auto *CF = dyn_cast<ConstantFP>(V)) {
|
2014-08-19 21:05:24 +02:00
|
|
|
if (CF->isNullValue())
|
2014-09-03 22:56:52 +02:00
|
|
|
Reg = fastMaterializeFloatZero(CF);
|
2014-08-19 21:05:24 +02:00
|
|
|
else
|
2011-04-28 00:41:55 +02:00
|
|
|
// Try to emit the constant directly.
|
2014-09-03 22:56:59 +02:00
|
|
|
Reg = fastEmit_f(VT, VT, ISD::ConstantFP, CF);
|
2008-08-27 20:10:19 +02:00
|
|
|
|
|
|
|
if (!Reg) {
|
2010-04-13 19:07:06 +02:00
|
|
|
// Try to emit the constant by using an integer constant with a cast.
|
2008-08-27 20:10:19 +02:00
|
|
|
const APFloat &Flt = CF->getValueAPF();
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT IntVT = TLI.getPointerTy(DL);
|
2008-08-27 20:10:19 +02:00
|
|
|
uint32_t IntBitWidth = IntVT.getSizeInBits();
|
2017-03-19 17:50:25 +01:00
|
|
|
APSInt SIntVal(IntBitWidth, /*isUnsigned=*/false);
|
2008-10-10 01:00:39 +02:00
|
|
|
bool isExact;
|
2017-03-19 17:50:25 +01:00
|
|
|
(void)Flt.convertToInteger(SIntVal, APFloat::rmTowardZero, &isExact);
|
2008-10-10 01:00:39 +02:00
|
|
|
if (isExact) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register IntegerReg =
|
2017-03-19 17:50:25 +01:00
|
|
|
getRegForValue(ConstantInt::get(V->getContext(), SIntVal));
|
2020-04-08 16:57:11 +02:00
|
|
|
if (IntegerReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
Reg = fastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP,
|
|
|
|
IntegerReg);
|
2008-09-20 00:16:54 +02:00
|
|
|
}
|
2008-08-27 20:10:19 +02:00
|
|
|
}
|
2014-09-03 20:46:45 +02:00
|
|
|
} else if (const auto *Op = dyn_cast<Operator>(V)) {
|
|
|
|
if (!selectOperator(Op, Op->getOpcode()))
|
2010-07-01 04:58:57 +02:00
|
|
|
if (!isa<Instruction>(Op) ||
|
2014-09-03 22:56:52 +02:00
|
|
|
!fastSelectInstruction(cast<Instruction>(Op)))
|
2010-07-01 04:58:57 +02:00
|
|
|
return 0;
|
2010-06-21 16:17:46 +02:00
|
|
|
Reg = lookUpRegForValue(Op);
|
2008-08-28 23:19:07 +02:00
|
|
|
} else if (isa<UndefValue>(V)) {
|
2008-09-04 01:32:19 +02:00
|
|
|
Reg = createResultReg(TLI.getRegClassFor(VT));
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
2010-07-10 11:00:22 +02:00
|
|
|
TII.get(TargetOpcode::IMPLICIT_DEF), Reg);
|
2008-08-27 20:10:19 +02:00
|
|
|
}
|
2014-08-19 21:05:24 +02:00
|
|
|
return Reg;
|
|
|
|
}
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
/// Helper for getRegForValue. This function is called when the value isn't
|
|
|
|
/// already available in a register and must be materialized with new
|
|
|
|
/// instructions.
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::materializeRegForValue(const Value *V, MVT VT) {
|
|
|
|
Register Reg;
|
2014-08-19 21:05:24 +02:00
|
|
|
// Give the target-specific code a try first.
|
|
|
|
if (isa<Constant>(V))
|
2014-09-03 22:56:52 +02:00
|
|
|
Reg = fastMaterializeConstant(cast<Constant>(V));
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2014-08-19 21:05:24 +02:00
|
|
|
// If target-specific code couldn't or didn't want to handle the value, then
|
|
|
|
// give target-independent code a try.
|
|
|
|
if (!Reg)
|
2014-09-03 20:46:45 +02:00
|
|
|
Reg = materializeConstant(V, VT);
|
2014-08-19 21:05:24 +02:00
|
|
|
|
2008-09-20 00:16:54 +02:00
|
|
|
// Don't cache constant materializations in the general ValueMap.
|
|
|
|
// To do so would require tracking what uses they dominate.
|
2014-08-19 21:05:24 +02:00
|
|
|
if (Reg) {
|
2008-09-25 03:28:51 +02:00
|
|
|
LocalValueMap[V] = Reg;
|
2010-07-10 11:00:22 +02:00
|
|
|
LastLocalValue = MRI.getVRegDef(Reg);
|
|
|
|
}
|
2008-09-04 01:32:19 +02:00
|
|
|
return Reg;
|
2008-08-27 20:10:19 +02:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::lookUpRegForValue(const Value *V) {
|
2008-09-09 03:26:59 +02:00
|
|
|
// Look up the value to see if we already have a register for it. We
|
|
|
|
// cache values defined by Instructions across blocks, and other values
|
|
|
|
// only locally. This is because Instructions already have the SSA
|
2010-05-04 01:36:34 +02:00
|
|
|
// def-dominates-use requirement enforced.
|
2020-04-08 18:26:32 +02:00
|
|
|
DenseMap<const Value *, Register>::iterator I = FuncInfo.ValueMap.find(V);
|
2010-07-07 18:29:44 +02:00
|
|
|
if (I != FuncInfo.ValueMap.end())
|
2010-06-21 16:21:47 +02:00
|
|
|
return I->second;
|
2012-10-03 10:10:01 +02:00
|
|
|
return LocalValueMap[V];
|
2008-09-09 03:26:59 +02:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
void FastISel::updateValueMap(const Value *I, Register Reg, unsigned NumRegs) {
|
2008-09-05 20:18:20 +02:00
|
|
|
if (!isa<Instruction>(I)) {
|
|
|
|
LocalValueMap[I] = Reg;
|
2011-05-16 23:06:17 +02:00
|
|
|
return;
|
2009-04-12 09:45:01 +02:00
|
|
|
}
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2020-04-08 18:26:32 +02:00
|
|
|
Register &AssignedReg = FuncInfo.ValueMap[I];
|
|
|
|
if (!AssignedReg)
|
2010-07-10 11:00:22 +02:00
|
|
|
// Use the new register.
|
2009-04-12 09:45:01 +02:00
|
|
|
AssignedReg = Reg;
|
2009-04-12 09:46:30 +02:00
|
|
|
else if (Reg != AssignedReg) {
|
2010-07-10 11:00:22 +02:00
|
|
|
// Arrange for uses of AssignedReg to be replaced by uses of Reg.
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
for (unsigned i = 0; i < NumRegs; i++) {
|
2014-09-03 20:46:45 +02:00
|
|
|
FuncInfo.RegFixups[AssignedReg + i] = Reg + i;
|
[FastISel] Sink local value materializations to first use
Summary:
Local values are constants, global addresses, and stack addresses that
can't be folded into the instruction that uses them. For example, when
storing the address of a global variable into memory, we need to
materialize that address into a register.
FastISel doesn't want to materialize any given local value more than
once, so it generates all local value materialization code at
EmitStartPt, which always dominates the current insertion point. This
allows it to maintain a map of local value registers, and it knows that
the local value area will always dominate the current insertion point.
The downside is that local value instructions are always emitted without
a source location. This is done to prevent jumpy line tables, but it
means that the local value area will be considered part of the previous
statement. Consider this C code:
call1(); // line 1
++global; // line 2
++global; // line 3
call2(&global, &local); // line 4
Today we end up with assembly and line tables like this:
.loc 1 1
callq call1
leaq global(%rip), %rdi
leaq local(%rsp), %rsi
.loc 1 2
addq $1, global(%rip)
.loc 1 3
addq $1, global(%rip)
.loc 1 4
callq call2
The LEA instructions in the local value area have no source location and
are treated as being on line 1. Stepping through the code in a debugger
and correlating it with the assembly won't make much sense, because
these materializations are only required for line 4.
This is actually problematic for the VS debugger "set next statement"
feature, which effectively assumes that there are no registers live
across statement boundaries. By sinking the local value code into the
statement and fixing up the source location, we can make that feature
work. This was filed as https://bugs.llvm.org/show_bug.cgi?id=35975 and
https://crbug.com/793819.
This change is obviously not enough to make this feature work reliably
in all cases, but I felt that it was worth doing anyway because it
usually generates smaller, more comprehensible -O0 code. I measured a
0.12% regression in code generation time with LLC on the sqlite3
amalgamation, so I think this is worth doing.
There are some special cases worth calling out in the commit message:
1. local values materialized for phis
2. local values used by no-op casts
3. dead local value code
Local values can be materialized for phis, and this does not show up as
a vreg use in MachineRegisterInfo. In this case, if there are no other
uses, this patch sinks the value to the first terminator, EH label, or
the end of the BB if nothing else exists.
Local values may also be used by no-op casts, which adds the register to
the RegFixups table. Without reversing the RegFixups map direction, we
don't have enough information to sink these instructions.
Lastly, if the local value register has no other uses, we can delete it.
This comes up when fastisel tries two instruction selection approaches
and the first materializes the value but fails and the second succeeds
without using the local value.
Reviewers: aprantl, dblaikie, qcolombet, MatzeB, vsk, echristo
Subscribers: dotdash, chandlerc, hans, sdardis, amccarth, javed.absar, zturner, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D43093
llvm-svn: 327581
2018-03-14 22:54:21 +01:00
|
|
|
FuncInfo.RegsWithFixups.insert(Reg + i);
|
|
|
|
}
|
2010-07-10 11:00:22 +02:00
|
|
|
|
|
|
|
AssignedReg = Reg;
|
2008-09-05 20:18:20 +02:00
|
|
|
}
|
2008-08-30 02:38:46 +02:00
|
|
|
}
|
|
|
|
|
2021-03-09 21:04:03 +01:00
|
|
|
Register FastISel::getRegForGEPIndex(const Value *Idx) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register IdxN = getRegForValue(Idx);
|
|
|
|
if (!IdxN)
|
2008-12-08 08:57:47 +01:00
|
|
|
// Unhandled operand. Halt "fast" selection and bail.
|
2021-03-09 21:04:03 +01:00
|
|
|
return Register();
|
2008-12-08 08:57:47 +01:00
|
|
|
|
|
|
|
// If the index is smaller or larger than intptr_t, truncate or extend it.
|
2015-07-09 04:09:04 +02:00
|
|
|
MVT PtrVT = TLI.getPointerTy(DL);
|
2009-08-11 00:56:29 +02:00
|
|
|
EVT IdxVT = EVT::getEVT(Idx->getType(), /*HandleUnknown=*/false);
|
2010-05-12 01:54:07 +02:00
|
|
|
if (IdxVT.bitsLT(PtrVT)) {
|
2021-03-09 21:04:03 +01:00
|
|
|
IdxN = fastEmit_r(IdxVT.getSimpleVT(), PtrVT, ISD::SIGN_EXTEND, IdxN);
|
2014-09-03 20:46:45 +02:00
|
|
|
} else if (IdxVT.bitsGT(PtrVT)) {
|
|
|
|
IdxN =
|
2021-03-09 21:04:03 +01:00
|
|
|
fastEmit_r(IdxVT.getSimpleVT(), PtrVT, ISD::TRUNCATE, IdxN);
|
2010-05-12 01:54:07 +02:00
|
|
|
}
|
2021-03-09 21:04:03 +01:00
|
|
|
return IdxN;
|
2008-12-08 08:57:47 +01:00
|
|
|
}
|
|
|
|
|
2010-07-10 11:00:22 +02:00
|
|
|
void FastISel::recomputeInsertPt() {
|
|
|
|
if (getLastLocalValue()) {
|
|
|
|
FuncInfo.InsertPt = getLastLocalValue();
|
2010-07-20 00:48:56 +02:00
|
|
|
FuncInfo.MBB = FuncInfo.InsertPt->getParent();
|
2010-07-10 11:00:22 +02:00
|
|
|
++FuncInfo.InsertPt;
|
|
|
|
} else
|
|
|
|
FuncInfo.InsertPt = FuncInfo.MBB->getFirstNonPHI();
|
|
|
|
|
|
|
|
// Now skip past any EH_LABELs, which must remain at the beginning.
|
|
|
|
while (FuncInfo.InsertPt != FuncInfo.MBB->end() &&
|
|
|
|
FuncInfo.InsertPt->getOpcode() == TargetOpcode::EH_LABEL)
|
|
|
|
++FuncInfo.InsertPt;
|
|
|
|
}
|
|
|
|
|
2011-11-29 20:40:47 +01:00
|
|
|
void FastISel::removeDeadCode(MachineBasicBlock::iterator I,
|
|
|
|
MachineBasicBlock::iterator E) {
|
ADT: Remove all ilist_iterator => pointer casts, NFC
Remove all ilist_iterator to pointer casts. There were two reasons for
casts:
- Checking for an uninitialized (i.e., null) iterator. I added
MachineInstrBundleIterator::isValid() to check for that case.
- Comparing an iterator against the underlying pointer value while
avoiding converting the pointer value to an iterator. This is
occasionally necessary in MachineInstrBundleIterator, since there is
an assertion in the constructors that the underlying MachineInstr is
not bundled (but we don't care about that if we're just checking for
pointer equality).
To support the latter case, I rewrote the == and != operators for
ilist_iterator and MachineInstrBundleIterator.
- The implicit constructors now use enable_if to exclude
const-iterator => non-const-iterator conversions from overload
resolution (previously it was a compiler error on instantiation, now
it's SFINAE).
- The == and != operators are now global (friends), and are not
templated.
- MachineInstrBundleIterator has overloads to compare against both
const_pointer and const_reference. This avoids the implicit
conversions to MachineInstrBundleIterator that assert, instead just
checking the address (and I added unit tests to confirm this).
Notably, the only remaining uses of ilist_iterator::getNodePtrUnchecked
are in ilist.h, and no code outside of ilist*.h directly relies on this
UB end-iterator-to-pointer conversion anymore. It's still needed for
ilist_*sentinel_traits, but I'll clean that up soon.
llvm-svn: 278478
2016-08-12 07:05:36 +02:00
|
|
|
assert(I.isValid() && E.isValid() && std::distance(I, E) > 0 &&
|
|
|
|
"Invalid iterator!");
|
2011-11-29 20:40:47 +01:00
|
|
|
while (I != E) {
|
2018-12-17 18:25:53 +01:00
|
|
|
if (SavedInsertPt == I)
|
|
|
|
SavedInsertPt = E;
|
|
|
|
if (EmitStartPt == I)
|
|
|
|
EmitStartPt = E.isValid() ? &*E : nullptr;
|
|
|
|
if (LastLocalValue == I)
|
|
|
|
LastLocalValue = E.isValid() ? &*E : nullptr;
|
|
|
|
|
2011-11-29 20:40:47 +01:00
|
|
|
MachineInstr *Dead = &*I;
|
|
|
|
++I;
|
|
|
|
Dead->eraseFromParent();
|
2013-03-08 23:56:31 +01:00
|
|
|
++NumFastIselDead;
|
2011-11-29 20:40:47 +01:00
|
|
|
}
|
|
|
|
recomputeInsertPt();
|
|
|
|
}
|
|
|
|
|
2012-10-03 10:10:01 +02:00
|
|
|
FastISel::SavePoint FastISel::enterLocalValueArea() {
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
SavePoint OldInsertPt = FuncInfo.InsertPt;
|
2010-07-10 11:00:22 +02:00
|
|
|
recomputeInsertPt();
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
return OldInsertPt;
|
2010-07-10 11:00:22 +02:00
|
|
|
}
|
|
|
|
|
2012-10-03 10:10:01 +02:00
|
|
|
void FastISel::leaveLocalValueArea(SavePoint OldInsertPt) {
|
2010-07-10 11:00:22 +02:00
|
|
|
if (FuncInfo.InsertPt != FuncInfo.MBB->begin())
|
2016-07-08 20:36:41 +02:00
|
|
|
LastLocalValue = &*std::prev(FuncInfo.InsertPt);
|
2010-07-10 11:00:22 +02:00
|
|
|
|
|
|
|
// Restore the previous insert position.
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
FuncInfo.InsertPt = OldInsertPt;
|
2010-07-10 11:00:22 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectBinaryOp(const User *I, unsigned ISDOpcode) {
|
2009-08-11 00:56:29 +02:00
|
|
|
EVT VT = EVT::getEVT(I->getType(), /*HandleUnknown=*/true);
|
2009-08-11 22:47:22 +02:00
|
|
|
if (VT == MVT::Other || !VT.isSimple())
|
2008-08-21 03:41:07 +02:00
|
|
|
// Unhandled type. Halt "fast" selection and bail.
|
|
|
|
return false;
|
2008-09-05 20:44:22 +02:00
|
|
|
|
2008-08-26 22:52:40 +02:00
|
|
|
// We only handle legal types. For example, on x86-32 the instruction
|
|
|
|
// selector contains all of the 64-bit instructions from x86-64,
|
|
|
|
// under the assumption that i64 won't be used if the target doesn't
|
|
|
|
// support it.
|
2008-09-05 20:44:22 +02:00
|
|
|
if (!TLI.isTypeLegal(VT)) {
|
2009-08-11 22:47:22 +02:00
|
|
|
// MVT::i1 is special. Allow AND, OR, or XOR because they
|
2008-09-05 20:44:22 +02:00
|
|
|
// don't require additional zeroing, which makes them easy.
|
2014-09-03 20:46:45 +02:00
|
|
|
if (VT == MVT::i1 && (ISDOpcode == ISD::AND || ISDOpcode == ISD::OR ||
|
|
|
|
ISDOpcode == ISD::XOR))
|
2009-08-12 02:36:31 +02:00
|
|
|
VT = TLI.getTypeToTransformTo(I->getContext(), VT);
|
2008-09-05 20:44:22 +02:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
2008-08-21 03:41:07 +02:00
|
|
|
|
2011-04-17 03:16:47 +02:00
|
|
|
// Check if the first operand is a constant, and handle it as "ri". At -O0,
|
|
|
|
// we don't have anything that canonicalizes operand order.
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *CI = dyn_cast<ConstantInt>(I->getOperand(0)))
|
2011-04-17 03:16:47 +02:00
|
|
|
if (isa<Instruction>(I) && cast<Instruction>(I)->isCommutative()) {
|
2020-05-28 23:54:49 +02:00
|
|
|
Register Op1 = getRegForValue(I->getOperand(1));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Op1)
|
|
|
|
return false;
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg =
|
2021-03-09 21:04:03 +01:00
|
|
|
fastEmit_ri_(VT.getSimpleVT(), ISDOpcode, Op1, CI->getZExtValue(),
|
|
|
|
VT.getSimpleVT());
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!ResultReg)
|
|
|
|
return false;
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2011-04-17 22:23:29 +02:00
|
|
|
// We successfully emitted code for the given LLVM Instruction.
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2011-04-17 22:23:29 +02:00
|
|
|
return true;
|
2011-04-17 03:16:47 +02:00
|
|
|
}
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Op0 = getRegForValue(I->getOperand(0));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Op0) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-20 02:35:17 +02:00
|
|
|
return false;
|
2010-05-12 01:54:07 +02:00
|
|
|
|
2008-08-21 03:41:07 +02:00
|
|
|
// Check if the second operand is a constant and handle it appropriately.
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
2015-04-07 00:29:07 +02:00
|
|
|
uint64_t Imm = CI->getSExtValue();
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2011-04-18 09:00:40 +02:00
|
|
|
// Transform "sdiv exact X, 8" -> "sra X, 3".
|
|
|
|
if (ISDOpcode == ISD::SDIV && isa<BinaryOperator>(I) &&
|
2014-09-03 20:46:45 +02:00
|
|
|
cast<BinaryOperator>(I)->isExact() && isPowerOf2_64(Imm)) {
|
2011-04-18 09:00:40 +02:00
|
|
|
Imm = Log2_64(Imm);
|
|
|
|
ISDOpcode = ISD::SRA;
|
|
|
|
}
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2012-03-22 01:21:17 +01:00
|
|
|
// Transform "urem x, pow2" -> "and x, pow2-1".
|
|
|
|
if (ISDOpcode == ISD::UREM && isa<BinaryOperator>(I) &&
|
|
|
|
isPowerOf2_64(Imm)) {
|
|
|
|
--Imm;
|
|
|
|
ISDOpcode = ISD::AND;
|
|
|
|
}
|
|
|
|
|
2021-03-09 21:04:03 +01:00
|
|
|
Register ResultReg = fastEmit_ri_(VT.getSimpleVT(), ISDOpcode, Op0, Imm,
|
|
|
|
VT.getSimpleVT());
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!ResultReg)
|
|
|
|
return false;
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2011-04-17 22:23:29 +02:00
|
|
|
// We successfully emitted code for the given LLVM Instruction.
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2011-04-17 22:23:29 +02:00
|
|
|
return true;
|
2008-08-21 03:41:07 +02:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Op1 = getRegForValue(I->getOperand(1));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Op1) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-20 02:11:48 +02:00
|
|
|
return false;
|
2010-05-12 01:54:07 +02:00
|
|
|
|
2008-08-27 20:10:19 +02:00
|
|
|
// Now we have both operands in registers. Emit the instruction.
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = fastEmit_rr(VT.getSimpleVT(), VT.getSimpleVT(),
|
2021-03-09 21:04:03 +01:00
|
|
|
ISDOpcode, Op0, Op1);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!ResultReg)
|
2008-08-20 02:11:48 +02:00
|
|
|
// Target-specific code wasn't able to find a machine opcode for
|
|
|
|
// the given ISD opcode and type. Halt "fast" selection and bail.
|
|
|
|
return false;
|
|
|
|
|
2008-08-20 02:23:20 +02:00
|
|
|
// We successfully emitted code for the given LLVM Instruction.
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2008-08-20 02:11:48 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectGetElementPtr(const User *I) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register N = getRegForValue(I->getOperand(0));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!N) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-21 00:45:34 +02:00
|
|
|
return false;
|
2020-09-14 21:52:54 +02:00
|
|
|
|
|
|
|
// FIXME: The code below does not handle vector GEPs. Halt "fast" selection
|
|
|
|
// and bail.
|
|
|
|
if (isa<VectorType>(I->getType()))
|
|
|
|
return false;
|
|
|
|
|
2011-11-17 08:15:58 +01:00
|
|
|
// Keep a running tab of the total offset to coalesce multiple N = N + Offset
|
|
|
|
// into a single N = N + TotalOffset.
|
|
|
|
uint64_t TotalOffs = 0;
|
|
|
|
// FIXME: What's a good SWAG number for MaxOffs?
|
|
|
|
uint64_t MaxOffs = 2048;
|
2015-07-09 04:09:04 +02:00
|
|
|
MVT VT = TLI.getPointerTy(DL);
|
2016-01-20 01:26:52 +01:00
|
|
|
for (gep_type_iterator GTI = gep_type_begin(I), E = gep_type_end(I);
|
|
|
|
GTI != E; ++GTI) {
|
|
|
|
const Value *Idx = GTI.getOperand();
|
2016-12-02 03:24:42 +01:00
|
|
|
if (StructType *StTy = GTI.getStructTypeOrNull()) {
|
2015-03-12 00:36:10 +01:00
|
|
|
uint64_t Field = cast<ConstantInt>(Idx)->getZExtValue();
|
2008-08-21 00:45:34 +02:00
|
|
|
if (Field) {
|
|
|
|
// N = N + Offset
|
2014-02-18 23:05:46 +01:00
|
|
|
TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field);
|
2011-11-17 08:15:58 +01:00
|
|
|
if (TotalOffs >= MaxOffs) {
|
2021-03-09 21:04:03 +01:00
|
|
|
N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!N) // Unhandled operand. Halt "fast" selection and bail.
|
2011-11-17 08:15:58 +01:00
|
|
|
return false;
|
|
|
|
TotalOffs = 0;
|
|
|
|
}
|
2008-08-21 00:45:34 +02:00
|
|
|
}
|
|
|
|
} else {
|
2016-01-20 01:26:52 +01:00
|
|
|
Type *Ty = GTI.getIndexedType();
|
2008-08-21 00:45:34 +02:00
|
|
|
|
|
|
|
// If this is a constant subscript, handle it quickly.
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
|
|
|
|
if (CI->isZero())
|
|
|
|
continue;
|
2011-11-17 08:15:58 +01:00
|
|
|
// N = N + Offset
|
2015-03-12 00:36:10 +01:00
|
|
|
uint64_t IdxN = CI->getValue().sextOrTrunc(64).getSExtValue();
|
|
|
|
TotalOffs += DL.getTypeAllocSize(Ty) * IdxN;
|
2011-11-17 08:15:58 +01:00
|
|
|
if (TotalOffs >= MaxOffs) {
|
2021-03-09 21:04:03 +01:00
|
|
|
N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!N) // Unhandled operand. Halt "fast" selection and bail.
|
2011-11-17 08:15:58 +01:00
|
|
|
return false;
|
|
|
|
TotalOffs = 0;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (TotalOffs) {
|
2021-03-09 21:04:03 +01:00
|
|
|
N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!N) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-21 00:45:34 +02:00
|
|
|
return false;
|
2011-11-17 08:15:58 +01:00
|
|
|
TotalOffs = 0;
|
2008-08-21 00:45:34 +02:00
|
|
|
}
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2008-08-21 00:45:34 +02:00
|
|
|
// N = N + Idx * ElementSize;
|
2014-02-18 23:05:46 +01:00
|
|
|
uint64_t ElementSize = DL.getTypeAllocSize(Ty);
|
2021-03-09 21:04:03 +01:00
|
|
|
Register IdxN = getRegForGEPIndex(Idx);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!IdxN) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-21 00:45:34 +02:00
|
|
|
return false;
|
|
|
|
|
2008-08-26 22:57:08 +02:00
|
|
|
if (ElementSize != 1) {
|
2021-03-09 21:04:03 +01:00
|
|
|
IdxN = fastEmit_ri_(VT, ISD::MUL, IdxN, ElementSize, VT);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!IdxN) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-26 22:57:08 +02:00
|
|
|
return false;
|
|
|
|
}
|
2021-03-09 21:04:03 +01:00
|
|
|
N = fastEmit_rr(VT, VT, ISD::ADD, N, IdxN);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!N) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-21 00:45:34 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2011-11-17 08:15:58 +01:00
|
|
|
if (TotalOffs) {
|
2021-03-09 21:04:03 +01:00
|
|
|
N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!N) // Unhandled operand. Halt "fast" selection and bail.
|
2011-11-17 08:15:58 +01:00
|
|
|
return false;
|
|
|
|
}
|
2008-08-21 00:45:34 +02:00
|
|
|
|
|
|
|
// We successfully emitted code for the given LLVM Instruction.
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, N);
|
2008-08-21 00:45:34 +02:00
|
|
|
return true;
|
2008-08-20 02:11:48 +02:00
|
|
|
}
|
|
|
|
|
2014-06-12 05:29:26 +02:00
|
|
|
bool FastISel::addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
|
|
|
|
const CallInst *CI, unsigned StartIdx) {
|
|
|
|
for (unsigned i = StartIdx, e = CI->getNumArgOperands(); i != e; ++i) {
|
|
|
|
Value *Val = CI->getArgOperand(i);
|
2014-07-02 00:25:49 +02:00
|
|
|
// Check for constants and encode them with a StackMaps::ConstantOp prefix.
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *C = dyn_cast<ConstantInt>(Val)) {
|
2014-06-12 05:29:26 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp));
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(C->getSExtValue()));
|
|
|
|
} else if (isa<ConstantPointerNull>(Val)) {
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp));
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(0));
|
|
|
|
} else if (auto *AI = dyn_cast<AllocaInst>(Val)) {
|
2016-11-20 14:14:57 +01:00
|
|
|
// Values coming from a stack location also require a special encoding,
|
2014-07-02 00:25:49 +02:00
|
|
|
// but that is added later on by the target specific frame index
|
|
|
|
// elimination implementation.
|
2014-06-12 05:29:26 +02:00
|
|
|
auto SI = FuncInfo.StaticAllocaMap.find(AI);
|
|
|
|
if (SI != FuncInfo.StaticAllocaMap.end())
|
|
|
|
Ops.push_back(MachineOperand::CreateFI(SI->second));
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
} else {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Reg = getRegForValue(Val);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Reg)
|
2014-06-12 05:29:26 +02:00
|
|
|
return false;
|
2019-07-16 06:46:31 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/false));
|
2014-06-12 05:29:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectStackmap(const CallInst *I) {
|
2014-07-02 00:25:49 +02:00
|
|
|
// void @llvm.experimental.stackmap(i64 <id>, i32 <numShadowBytes>,
|
|
|
|
// [live variables...])
|
|
|
|
assert(I->getCalledFunction()->getReturnType()->isVoidTy() &&
|
|
|
|
"Stackmap cannot return a value.");
|
|
|
|
|
|
|
|
// The stackmap intrinsic only records the live variables (the arguments
|
|
|
|
// passed to it) and emits NOPS (if requested). Unlike the patchpoint
|
|
|
|
// intrinsic, this won't be lowered to a function call. This means we don't
|
|
|
|
// have to worry about calling conventions and target-specific lowering code.
|
|
|
|
// Instead we perform the call lowering right here.
|
|
|
|
//
|
2017-05-09 15:35:13 +02:00
|
|
|
// CALLSEQ_START(0, 0...)
|
2014-07-02 00:25:49 +02:00
|
|
|
// STACKMAP(id, nbytes, ...)
|
|
|
|
// CALLSEQ_END(0, 0)
|
|
|
|
//
|
|
|
|
SmallVector<MachineOperand, 32> Ops;
|
|
|
|
|
|
|
|
// Add the <id> and <numBytes> constants.
|
|
|
|
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)) &&
|
|
|
|
"Expected a constant integer.");
|
|
|
|
const auto *ID = cast<ConstantInt>(I->getOperand(PatchPointOpers::IDPos));
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(ID->getZExtValue()));
|
|
|
|
|
|
|
|
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)) &&
|
|
|
|
"Expected a constant integer.");
|
|
|
|
const auto *NumBytes =
|
2014-09-03 20:46:45 +02:00
|
|
|
cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos));
|
2014-07-02 00:25:49 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue()));
|
|
|
|
|
|
|
|
// Push live variables for the stack map (skipping the first two arguments
|
|
|
|
// <id> and <numBytes>).
|
|
|
|
if (!addStackMapLiveVars(Ops, I, 2))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// We are not adding any register mask info here, because the stackmap doesn't
|
|
|
|
// clobber anything.
|
|
|
|
|
|
|
|
// Add scratch registers as implicit def and early clobber.
|
|
|
|
CallingConv::ID CC = I->getCallingConv();
|
|
|
|
const MCPhysReg *ScratchRegs = TLI.getScratchRegisters(CC);
|
|
|
|
for (unsigned i = 0; ScratchRegs[i]; ++i)
|
|
|
|
Ops.push_back(MachineOperand::CreateReg(
|
2019-07-16 06:46:31 +02:00
|
|
|
ScratchRegs[i], /*isDef=*/true, /*isImp=*/true, /*isKill=*/false,
|
|
|
|
/*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/true));
|
2014-07-02 00:25:49 +02:00
|
|
|
|
|
|
|
// Issue CALLSEQ_START
|
|
|
|
unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
|
2015-08-10 23:27:03 +02:00
|
|
|
auto Builder =
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackDown));
|
|
|
|
const MCInstrDesc &MCID = Builder.getInstr()->getDesc();
|
|
|
|
for (unsigned I = 0, E = MCID.getNumOperands(); I < E; ++I)
|
|
|
|
Builder.addImm(0);
|
2014-07-02 00:25:49 +02:00
|
|
|
|
|
|
|
// Issue STACKMAP.
|
|
|
|
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::STACKMAP));
|
|
|
|
for (auto const &MO : Ops)
|
2017-01-13 10:58:52 +01:00
|
|
|
MIB.add(MO);
|
2014-07-02 00:25:49 +02:00
|
|
|
|
|
|
|
// Issue CALLSEQ_END
|
|
|
|
unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackUp))
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(0)
|
|
|
|
.addImm(0);
|
2014-07-02 00:25:49 +02:00
|
|
|
|
|
|
|
// Inform the Frame Information that we have a stackmap in this function.
|
2016-07-28 20:40:00 +02:00
|
|
|
FuncInfo.MF->getFrameInfo().setHasStackMap();
|
2014-07-02 00:25:49 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Lower an argument list according to the target calling convention.
|
2014-07-12 00:19:02 +02:00
|
|
|
///
|
|
|
|
/// This is a helper for lowering intrinsics that follow a target calling
|
|
|
|
/// convention or require stack pointer adjustment. Only a subset of the
|
|
|
|
/// intrinsic's operands need to participate in the calling convention.
|
|
|
|
bool FastISel::lowerCallOperands(const CallInst *CI, unsigned ArgIdx,
|
|
|
|
unsigned NumArgs, const Value *Callee,
|
|
|
|
bool ForceRetVoidTy, CallLoweringInfo &CLI) {
|
|
|
|
ArgListTy Args;
|
|
|
|
Args.reserve(NumArgs);
|
|
|
|
|
|
|
|
// Populate the argument list.
|
2017-04-14 22:19:02 +02:00
|
|
|
for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs; ArgI != ArgE; ++ArgI) {
|
2014-07-12 00:19:02 +02:00
|
|
|
Value *V = CI->getOperand(ArgI);
|
|
|
|
|
|
|
|
assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic.");
|
|
|
|
|
|
|
|
ArgListEntry Entry;
|
|
|
|
Entry.Val = V;
|
|
|
|
Entry.Ty = V->getType();
|
2020-04-11 09:35:32 +02:00
|
|
|
Entry.setAttributes(CI, ArgI);
|
2014-07-12 00:19:02 +02:00
|
|
|
Args.push_back(Entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
Type *RetTy = ForceRetVoidTy ? Type::getVoidTy(CI->getType()->getContext())
|
|
|
|
: CI->getType();
|
|
|
|
CLI.setCallee(CI->getCallingConv(), RetTy, Callee, std::move(Args), NumArgs);
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
return lowerCallTo(CLI);
|
2014-07-12 00:19:02 +02:00
|
|
|
}
|
|
|
|
|
2015-06-23 14:21:54 +02:00
|
|
|
FastISel::CallLoweringInfo &FastISel::CallLoweringInfo::setCallee(
|
|
|
|
const DataLayout &DL, MCContext &Ctx, CallingConv::ID CC, Type *ResultTy,
|
2016-10-05 03:37:29 +02:00
|
|
|
StringRef Target, ArgListTy &&ArgsList, unsigned FixedArgs) {
|
2015-06-23 14:21:54 +02:00
|
|
|
SmallString<32> MangledName;
|
|
|
|
Mangler::getNameWithPrefix(MangledName, Target, DL);
|
|
|
|
MCSymbol *Sym = Ctx.getOrCreateSymbol(MangledName);
|
|
|
|
return setCallee(CC, ResultTy, Sym, std::move(ArgsList), FixedArgs);
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectPatchpoint(const CallInst *I) {
|
2014-07-12 00:19:02 +02:00
|
|
|
// void|i64 @llvm.experimental.patchpoint.void|i64(i64 <id>,
|
|
|
|
// i32 <numBytes>,
|
|
|
|
// i8* <target>,
|
|
|
|
// i32 <numArgs>,
|
|
|
|
// [Args...],
|
|
|
|
// [live variables...])
|
|
|
|
CallingConv::ID CC = I->getCallingConv();
|
|
|
|
bool IsAnyRegCC = CC == CallingConv::AnyReg;
|
|
|
|
bool HasDef = !I->getType()->isVoidTy();
|
2015-04-22 08:02:31 +02:00
|
|
|
Value *Callee = I->getOperand(PatchPointOpers::TargetPos)->stripPointerCasts();
|
2014-07-12 00:19:02 +02:00
|
|
|
|
|
|
|
// Get the real number of arguments participating in the call <numArgs>
|
|
|
|
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos)) &&
|
|
|
|
"Expected a constant integer.");
|
|
|
|
const auto *NumArgsVal =
|
2014-09-03 20:46:45 +02:00
|
|
|
cast<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos));
|
2014-07-12 00:19:02 +02:00
|
|
|
unsigned NumArgs = NumArgsVal->getZExtValue();
|
|
|
|
|
|
|
|
// Skip the four meta args: <id>, <numNopBytes>, <target>, <numArgs>
|
|
|
|
// This includes all meta-operands up to but not including CC.
|
|
|
|
unsigned NumMetaOpers = PatchPointOpers::CCPos;
|
|
|
|
assert(I->getNumArgOperands() >= NumMetaOpers + NumArgs &&
|
|
|
|
"Not enough arguments provided to the patchpoint intrinsic");
|
|
|
|
|
|
|
|
// For AnyRegCC the arguments are lowered later on manually.
|
|
|
|
unsigned NumCallArgs = IsAnyRegCC ? 0 : NumArgs;
|
|
|
|
CallLoweringInfo CLI;
|
2015-01-13 18:48:04 +01:00
|
|
|
CLI.setIsPatchPoint();
|
2014-07-12 00:19:02 +02:00
|
|
|
if (!lowerCallOperands(I, NumMetaOpers, NumCallArgs, Callee, IsAnyRegCC, CLI))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
assert(CLI.Call && "No call instruction specified.");
|
|
|
|
|
|
|
|
SmallVector<MachineOperand, 32> Ops;
|
|
|
|
|
|
|
|
// Add an explicit result reg if we use the anyreg calling convention.
|
|
|
|
if (IsAnyRegCC && HasDef) {
|
2014-07-15 04:22:43 +02:00
|
|
|
assert(CLI.NumResultRegs == 0 && "Unexpected result register.");
|
|
|
|
CLI.ResultReg = createResultReg(TLI.getRegClassFor(MVT::i64));
|
|
|
|
CLI.NumResultRegs = 1;
|
2019-07-16 06:46:31 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(CLI.ResultReg, /*isDef=*/true));
|
2014-07-12 00:19:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add the <id> and <numBytes> constants.
|
|
|
|
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)) &&
|
|
|
|
"Expected a constant integer.");
|
|
|
|
const auto *ID = cast<ConstantInt>(I->getOperand(PatchPointOpers::IDPos));
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(ID->getZExtValue()));
|
|
|
|
|
|
|
|
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)) &&
|
|
|
|
"Expected a constant integer.");
|
|
|
|
const auto *NumBytes =
|
2014-09-03 20:46:45 +02:00
|
|
|
cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos));
|
2014-07-12 00:19:02 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue()));
|
|
|
|
|
2015-04-22 08:02:31 +02:00
|
|
|
// Add the call target.
|
|
|
|
if (const auto *C = dyn_cast<IntToPtrInst>(Callee)) {
|
|
|
|
uint64_t CalleeConstAddr =
|
|
|
|
cast<ConstantInt>(C->getOperand(0))->getZExtValue();
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr));
|
|
|
|
} else if (const auto *C = dyn_cast<ConstantExpr>(Callee)) {
|
|
|
|
if (C->getOpcode() == Instruction::IntToPtr) {
|
|
|
|
uint64_t CalleeConstAddr =
|
|
|
|
cast<ConstantInt>(C->getOperand(0))->getZExtValue();
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr));
|
|
|
|
} else
|
2014-07-12 00:19:02 +02:00
|
|
|
llvm_unreachable("Unsupported ConstantExpr.");
|
2015-04-22 08:02:31 +02:00
|
|
|
} else if (const auto *GV = dyn_cast<GlobalValue>(Callee)) {
|
|
|
|
Ops.push_back(MachineOperand::CreateGA(GV, 0));
|
2014-07-12 00:19:02 +02:00
|
|
|
} else if (isa<ConstantPointerNull>(Callee))
|
2015-04-22 08:02:31 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateImm(0));
|
2014-07-12 00:19:02 +02:00
|
|
|
else
|
|
|
|
llvm_unreachable("Unsupported callee address.");
|
|
|
|
|
|
|
|
// Adjust <numArgs> to account for any arguments that have been passed on
|
|
|
|
// the stack instead.
|
|
|
|
unsigned NumCallRegArgs = IsAnyRegCC ? NumArgs : CLI.OutRegs.size();
|
|
|
|
Ops.push_back(MachineOperand::CreateImm(NumCallRegArgs));
|
|
|
|
|
|
|
|
// Add the calling convention
|
|
|
|
Ops.push_back(MachineOperand::CreateImm((unsigned)CC));
|
|
|
|
|
|
|
|
// Add the arguments we omitted previously. The register allocator should
|
|
|
|
// place these in any free register.
|
|
|
|
if (IsAnyRegCC) {
|
|
|
|
for (unsigned i = NumMetaOpers, e = NumMetaOpers + NumArgs; i != e; ++i) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Reg = getRegForValue(I->getArgOperand(i));
|
2014-07-12 00:19:02 +02:00
|
|
|
if (!Reg)
|
|
|
|
return false;
|
2019-07-16 06:46:31 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/false));
|
2014-07-12 00:19:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push the arguments from the call instruction.
|
|
|
|
for (auto Reg : CLI.OutRegs)
|
2019-07-16 06:46:31 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/false));
|
2014-07-12 00:19:02 +02:00
|
|
|
|
|
|
|
// Push live variables for the stack map.
|
|
|
|
if (!addStackMapLiveVars(Ops, I, NumMetaOpers + NumArgs))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Push the register mask info.
|
2015-03-11 23:42:13 +01:00
|
|
|
Ops.push_back(MachineOperand::CreateRegMask(
|
|
|
|
TRI.getCallPreservedMask(*FuncInfo.MF, CC)));
|
2014-07-12 00:19:02 +02:00
|
|
|
|
|
|
|
// Add scratch registers as implicit def and early clobber.
|
|
|
|
const MCPhysReg *ScratchRegs = TLI.getScratchRegisters(CC);
|
|
|
|
for (unsigned i = 0; ScratchRegs[i]; ++i)
|
|
|
|
Ops.push_back(MachineOperand::CreateReg(
|
2019-07-16 06:46:31 +02:00
|
|
|
ScratchRegs[i], /*isDef=*/true, /*isImp=*/true, /*isKill=*/false,
|
|
|
|
/*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/true));
|
2014-07-12 00:19:02 +02:00
|
|
|
|
|
|
|
// Add implicit defs (return values).
|
|
|
|
for (auto Reg : CLI.InRegs)
|
2019-07-16 06:46:31 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/true,
|
|
|
|
/*isImp=*/true));
|
2014-07-12 00:19:02 +02:00
|
|
|
|
2014-07-15 04:22:46 +02:00
|
|
|
// Insert the patchpoint instruction before the call generated by the target.
|
|
|
|
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, CLI.Call, DbgLoc,
|
2014-07-12 00:19:02 +02:00
|
|
|
TII.get(TargetOpcode::PATCHPOINT));
|
|
|
|
|
|
|
|
for (auto &MO : Ops)
|
2017-01-13 10:58:52 +01:00
|
|
|
MIB.add(MO);
|
2014-07-12 00:19:02 +02:00
|
|
|
|
|
|
|
MIB->setPhysRegsDeadExcept(CLI.InRegs, TRI);
|
|
|
|
|
|
|
|
// Delete the original call instruction.
|
|
|
|
CLI.Call->eraseFromParent();
|
|
|
|
|
|
|
|
// Inform the Frame Information that we have a patchpoint in this function.
|
2016-07-28 20:40:00 +02:00
|
|
|
FuncInfo.MF->getFrameInfo().setHasPatchPoint();
|
2014-07-12 00:19:02 +02:00
|
|
|
|
2014-07-15 04:22:43 +02:00
|
|
|
if (CLI.NumResultRegs)
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, CLI.ResultReg, CLI.NumResultRegs);
|
2014-07-12 00:19:02 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 07:45:21 +02:00
|
|
|
bool FastISel::selectXRayCustomEvent(const CallInst *I) {
|
|
|
|
const auto &Triple = TM.getTargetTriple();
|
|
|
|
if (Triple.getArch() != Triple::x86_64 || !Triple.isOSLinux())
|
|
|
|
return true; // don't do anything to this instruction.
|
|
|
|
SmallVector<MachineOperand, 8> Ops;
|
|
|
|
Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(0)),
|
2019-07-16 06:46:31 +02:00
|
|
|
/*isDef=*/false));
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 07:45:21 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(1)),
|
2019-07-16 06:46:31 +02:00
|
|
|
/*isDef=*/false));
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 07:45:21 +02:00
|
|
|
MachineInstrBuilder MIB =
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::PATCHABLE_EVENT_CALL));
|
|
|
|
for (auto &MO : Ops)
|
|
|
|
MIB.add(MO);
|
[XRay][compiler-rt+llvm] Update XRay register stashing semantics
Summary:
This change expands the amount of registers stashed by the entry and
`__xray_CustomEvent` trampolines.
We've found that since the `__xray_CustomEvent` trampoline calls can show up in
situations where the scratch registers are being used, and since we don't
typically want to affect the code-gen around the disabled
`__xray_customevent(...)` intrinsic calls, that we need to save and restore the
state of even the scratch registers in the handling of these custom events.
Reviewers: pcc, pelikan, dblaikie, eizan, kpw, echristo, chandlerc
Reviewed By: echristo
Subscribers: chandlerc, echristo, hiraditya, davide, dblaikie, llvm-commits
Differential Revision: https://reviews.llvm.org/D40894
llvm-svn: 323940
2018-02-01 03:21:54 +01:00
|
|
|
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 07:45:21 +02:00
|
|
|
// Insert the Patchable Event Call instruction, that gets lowered properly.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-04-17 23:30:29 +02:00
|
|
|
bool FastISel::selectXRayTypedEvent(const CallInst *I) {
|
|
|
|
const auto &Triple = TM.getTargetTriple();
|
|
|
|
if (Triple.getArch() != Triple::x86_64 || !Triple.isOSLinux())
|
|
|
|
return true; // don't do anything to this instruction.
|
|
|
|
SmallVector<MachineOperand, 8> Ops;
|
|
|
|
Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(0)),
|
2019-07-16 06:46:31 +02:00
|
|
|
/*isDef=*/false));
|
2018-04-17 23:30:29 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(1)),
|
2019-07-16 06:46:31 +02:00
|
|
|
/*isDef=*/false));
|
2018-04-17 23:30:29 +02:00
|
|
|
Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(2)),
|
2019-07-16 06:46:31 +02:00
|
|
|
/*isDef=*/false));
|
2018-04-17 23:30:29 +02:00
|
|
|
MachineInstrBuilder MIB =
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::PATCHABLE_TYPED_EVENT_CALL));
|
|
|
|
for (auto &MO : Ops)
|
|
|
|
MIB.add(MO);
|
|
|
|
|
|
|
|
// Insert the Patchable Typed Event Call instruction, that gets lowered properly.
|
|
|
|
return true;
|
|
|
|
}
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 07:45:21 +02:00
|
|
|
|
Rename AttributeSet to AttributeList
Summary:
This class is a list of AttributeSetNodes corresponding the function
prototype of a call or function declaration. This class used to be
called ParamAttrListPtr, then AttrListPtr, then AttributeSet. It is
typically accessed by parameter and return value index, so
"AttributeList" seems like a more intuitive name.
Rename AttributeSetImpl to AttributeListImpl to follow suit.
It's useful to rename this class so that we can rename AttributeSetNode
to AttributeSet later. AttributeSet is the set of attributes that apply
to a single function, argument, or return value.
Reviewers: sanjoy, javed.absar, chandlerc, pete
Reviewed By: pete
Subscribers: pete, jholewinski, arsenm, dschuff, mehdi_amini, jfb, nhaehnle, sbc100, void, llvm-commits
Differential Revision: https://reviews.llvm.org/D31102
llvm-svn: 298393
2017-03-21 17:57:19 +01:00
|
|
|
/// Returns an AttributeList representing the attributes applied to the return
|
2014-07-12 00:01:42 +02:00
|
|
|
/// value of the given call.
|
Rename AttributeSet to AttributeList
Summary:
This class is a list of AttributeSetNodes corresponding the function
prototype of a call or function declaration. This class used to be
called ParamAttrListPtr, then AttrListPtr, then AttributeSet. It is
typically accessed by parameter and return value index, so
"AttributeList" seems like a more intuitive name.
Rename AttributeSetImpl to AttributeListImpl to follow suit.
It's useful to rename this class so that we can rename AttributeSetNode
to AttributeSet later. AttributeSet is the set of attributes that apply
to a single function, argument, or return value.
Reviewers: sanjoy, javed.absar, chandlerc, pete
Reviewed By: pete
Subscribers: pete, jholewinski, arsenm, dschuff, mehdi_amini, jfb, nhaehnle, sbc100, void, llvm-commits
Differential Revision: https://reviews.llvm.org/D31102
llvm-svn: 298393
2017-03-21 17:57:19 +01:00
|
|
|
static AttributeList getReturnAttrs(FastISel::CallLoweringInfo &CLI) {
|
2014-07-12 00:01:42 +02:00
|
|
|
SmallVector<Attribute::AttrKind, 2> Attrs;
|
|
|
|
if (CLI.RetSExt)
|
|
|
|
Attrs.push_back(Attribute::SExt);
|
|
|
|
if (CLI.RetZExt)
|
|
|
|
Attrs.push_back(Attribute::ZExt);
|
|
|
|
if (CLI.IsInReg)
|
|
|
|
Attrs.push_back(Attribute::InReg);
|
|
|
|
|
Rename AttributeSet to AttributeList
Summary:
This class is a list of AttributeSetNodes corresponding the function
prototype of a call or function declaration. This class used to be
called ParamAttrListPtr, then AttrListPtr, then AttributeSet. It is
typically accessed by parameter and return value index, so
"AttributeList" seems like a more intuitive name.
Rename AttributeSetImpl to AttributeListImpl to follow suit.
It's useful to rename this class so that we can rename AttributeSetNode
to AttributeSet later. AttributeSet is the set of attributes that apply
to a single function, argument, or return value.
Reviewers: sanjoy, javed.absar, chandlerc, pete
Reviewed By: pete
Subscribers: pete, jholewinski, arsenm, dschuff, mehdi_amini, jfb, nhaehnle, sbc100, void, llvm-commits
Differential Revision: https://reviews.llvm.org/D31102
llvm-svn: 298393
2017-03-21 17:57:19 +01:00
|
|
|
return AttributeList::get(CLI.RetTy->getContext(), AttributeList::ReturnIndex,
|
|
|
|
Attrs);
|
2014-07-12 00:01:42 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
bool FastISel::lowerCallTo(const CallInst *CI, const char *SymName,
|
2014-07-12 00:01:42 +02:00
|
|
|
unsigned NumArgs) {
|
2015-06-23 14:21:54 +02:00
|
|
|
MCContext &Ctx = MF->getContext();
|
|
|
|
SmallString<32> MangledName;
|
|
|
|
Mangler::getNameWithPrefix(MangledName, SymName, DL);
|
|
|
|
MCSymbol *Sym = Ctx.getOrCreateSymbol(MangledName);
|
|
|
|
return lowerCallTo(CI, Sym, NumArgs);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FastISel::lowerCallTo(const CallInst *CI, MCSymbol *Symbol,
|
|
|
|
unsigned NumArgs) {
|
2020-04-11 09:35:32 +02:00
|
|
|
FunctionType *FTy = CI->getFunctionType();
|
|
|
|
Type *RetTy = CI->getType();
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
ArgListTy Args;
|
|
|
|
Args.reserve(NumArgs);
|
|
|
|
|
|
|
|
// Populate the argument list.
|
|
|
|
// Attributes for args start at offset 1, after the return attribute.
|
|
|
|
for (unsigned ArgI = 0; ArgI != NumArgs; ++ArgI) {
|
|
|
|
Value *V = CI->getOperand(ArgI);
|
|
|
|
|
|
|
|
assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic.");
|
|
|
|
|
|
|
|
ArgListEntry Entry;
|
|
|
|
Entry.Val = V;
|
|
|
|
Entry.Ty = V->getType();
|
2020-04-11 09:35:32 +02:00
|
|
|
Entry.setAttributes(CI, ArgI);
|
2014-07-12 00:01:42 +02:00
|
|
|
Args.push_back(Entry);
|
|
|
|
}
|
2020-04-11 09:35:32 +02:00
|
|
|
TLI.markLibCallAttributes(MF, CI->getCallingConv(), Args);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
CallLoweringInfo CLI;
|
2020-04-13 01:47:06 +02:00
|
|
|
CLI.setCallee(RetTy, FTy, Symbol, std::move(Args), *CI, NumArgs);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
return lowerCallTo(CLI);
|
2014-07-12 00:01:42 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::lowerCallTo(CallLoweringInfo &CLI) {
|
2014-07-12 00:01:42 +02:00
|
|
|
// Handle the incoming return values from the call.
|
|
|
|
CLI.clearIns();
|
|
|
|
SmallVector<EVT, 4> RetTys;
|
2015-07-09 03:57:34 +02:00
|
|
|
ComputeValueVTs(TLI, DL, CLI.RetTy, RetTys);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
SmallVector<ISD::OutputArg, 4> Outs;
|
2018-07-28 15:25:19 +02:00
|
|
|
GetReturnInfo(CLI.CallConv, CLI.RetTy, getReturnAttrs(CLI), Outs, TLI, DL);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool CanLowerReturn = TLI.CanLowerReturn(
|
|
|
|
CLI.CallConv, *FuncInfo.MF, CLI.IsVarArg, Outs, CLI.RetTy->getContext());
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
// FIXME: sret demotion isn't supported yet - bail out.
|
|
|
|
if (!CanLowerReturn)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (unsigned I = 0, E = RetTys.size(); I != E; ++I) {
|
|
|
|
EVT VT = RetTys[I];
|
|
|
|
MVT RegisterVT = TLI.getRegisterType(CLI.RetTy->getContext(), VT);
|
|
|
|
unsigned NumRegs = TLI.getNumRegisters(CLI.RetTy->getContext(), VT);
|
|
|
|
for (unsigned i = 0; i != NumRegs; ++i) {
|
|
|
|
ISD::InputArg MyFlags;
|
|
|
|
MyFlags.VT = RegisterVT;
|
|
|
|
MyFlags.ArgVT = VT;
|
|
|
|
MyFlags.Used = CLI.IsReturnValueUsed;
|
|
|
|
if (CLI.RetSExt)
|
|
|
|
MyFlags.Flags.setSExt();
|
|
|
|
if (CLI.RetZExt)
|
|
|
|
MyFlags.Flags.setZExt();
|
|
|
|
if (CLI.IsInReg)
|
|
|
|
MyFlags.Flags.setInReg();
|
|
|
|
CLI.Ins.push_back(MyFlags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle all of the outgoing arguments.
|
|
|
|
CLI.clearOuts();
|
|
|
|
for (auto &Arg : CLI.getArgs()) {
|
|
|
|
Type *FinalType = Arg.Ty;
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsByVal)
|
2021-07-13 06:14:35 +02:00
|
|
|
FinalType = Arg.IndirectType;
|
2014-07-12 00:01:42 +02:00
|
|
|
bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
|
2021-06-09 18:36:39 +02:00
|
|
|
FinalType, CLI.CallConv, CLI.IsVarArg, DL);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
ISD::ArgFlagsTy Flags;
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsZExt)
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setZExt();
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsSExt)
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setSExt();
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsInReg)
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setInReg();
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsSRet)
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setSRet();
|
2016-03-29 19:37:21 +02:00
|
|
|
if (Arg.IsSwiftSelf)
|
|
|
|
Flags.setSwiftSelf();
|
2021-01-20 11:14:03 +01:00
|
|
|
if (Arg.IsSwiftAsync)
|
|
|
|
Flags.setSwiftAsync();
|
2016-04-01 23:41:15 +02:00
|
|
|
if (Arg.IsSwiftError)
|
|
|
|
Flags.setSwiftError();
|
Add Windows Control Flow Guard checks (/guard:cf).
Summary:
A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on
indirect function calls, using either the check mechanism (X86, ARM, AArch64) or
or the dispatch mechanism (X86-64). The check mechanism requires a new calling
convention for the supported targets. The dispatch mechanism adds the target as
an operand bundle, which is processed by SelectionDAG. Another pass
(CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as
required by /guard:cf. This feature is enabled using the `cfguard` CC1 option.
Reviewers: thakis, rnk, theraven, pcc
Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D65761
2019-10-28 14:22:19 +01:00
|
|
|
if (Arg.IsCFGuardTarget)
|
|
|
|
Flags.setCFGuardTarget();
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsByVal)
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setByVal();
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsInAlloca) {
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setInAlloca();
|
|
|
|
// Set the byval flag for CCAssignFn callbacks that don't know about
|
|
|
|
// inalloca. This way we can know how many bytes we should've allocated
|
|
|
|
// and how many bytes a callee cleanup function will pop. If we port
|
|
|
|
// inalloca to more targets, we'll have to add custom inalloca handling in
|
|
|
|
// the various CC lowering callbacks.
|
|
|
|
Flags.setByVal();
|
|
|
|
}
|
Reland [X86] Codegen for preallocated
See https://reviews.llvm.org/D74651 for the preallocated IR constructs
and LangRef changes.
In X86TargetLowering::LowerCall(), if a call is preallocated, record
each argument's offset from the stack pointer and the total stack
adjustment. Associate the call Value with an integer index. Store the
info in X86MachineFunctionInfo with the integer index as the key.
This adds two new target independent ISDOpcodes and two new target
dependent Opcodes corresponding to @llvm.call.preallocated.{setup,arg}.
The setup ISelDAG node takes in a chain and outputs a chain and a
SrcValue of the preallocated call Value. It is lowered to a target
dependent node with the SrcValue replaced with the integer index key by
looking in X86MachineFunctionInfo. In
X86TargetLowering::EmitInstrWithCustomInserter() this is lowered to an
%esp adjustment, the exact amount determined by looking in
X86MachineFunctionInfo with the integer index key.
The arg ISelDAG node takes in a chain, a SrcValue of the preallocated
call Value, and the arg index int constant. It produces a chain and the
pointer fo the arg. It is lowered to a target dependent node with the
SrcValue replaced with the integer index key by looking in
X86MachineFunctionInfo. In
X86TargetLowering::EmitInstrWithCustomInserter() this is lowered to a
lea of the stack pointer plus an offset determined by looking in
X86MachineFunctionInfo with the integer index key.
Force any function containing a preallocated call to use the frame
pointer.
Does not yet handle a setup without a call, or a conditional call.
Does not yet handle musttail. That requires a LangRef change first.
Tried to look at all references to inalloca and see if they apply to
preallocated. I've made preallocated versions of tests testing inalloca
whenever possible and when they make sense (e.g. not alloca related,
inalloca edge cases).
Aside from the tests added here, I checked that this codegen produces
correct code for something like
```
struct A {
A();
A(A&&);
~A();
};
void bar() {
foo(foo(foo(foo(foo(A(), 4), 5), 6), 7), 8);
}
```
by replacing the inalloca version of the .ll file with the appropriate
preallocated code. Running the executable produces the same results as
using the current inalloca implementation.
Reverted due to unexpectedly passing tests, added REQUIRES: asserts for reland.
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77689
2020-03-16 20:32:36 +01:00
|
|
|
if (Arg.IsPreallocated) {
|
|
|
|
Flags.setPreallocated();
|
|
|
|
// Set the byval flag for CCAssignFn callbacks that don't know about
|
|
|
|
// preallocated. This way we can know how many bytes we should've
|
|
|
|
// allocated and how many bytes a callee cleanup function will pop. If we
|
|
|
|
// port preallocated to more targets, we'll have to add custom
|
|
|
|
// preallocated handling in the various CC lowering callbacks.
|
|
|
|
Flags.setByVal();
|
|
|
|
}
|
[clang][AArch64] Correctly align HFA arguments when passed on the stack
When we pass a AArch64 Homogeneous Floating-Point
Aggregate (HFA) argument with increased alignment
requirements, for example
struct S {
__attribute__ ((__aligned__(16))) double v[4];
};
Clang uses `[4 x double]` for the parameter, which is passed
on the stack at alignment 8, whereas it should be at
alignment 16, following Rule C.4 in
AAPCS (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#642parameter-passing-rules)
Currently we don't have a way to express in LLVM IR the
alignment requirements of the function arguments. The align
attribute is applicable to pointers only, and only for some
special ways of passing arguments (e..g byval). When
implementing AAPCS32/AAPCS64, clang resorts to dubious hacks
of coercing to types, which naturally have the needed
alignment. We don't have enough types to cover all the
cases, though.
This patch introduces a new use of the stackalign attribute
to control stack slot alignment, when and if an argument is
passed in memory.
The attribute align is left as an optimizer hint - it still
applies to pointer types only and pertains to the content of
the pointer, whereas the alignment of the pointer itself is
determined by the stackalign attribute.
For byval arguments, the stackalign attribute assumes the
role, previously perfomed by align, falling back to align if
stackalign` is absent.
On the clang side, when passing arguments using the "direct"
style (cf. `ABIArgInfo::Kind`), now we can optionally
specify an alignment, which is emitted as the new
`stackalign` attribute.
Patch by Momchil Velikov and Lucas Prates.
Differential Revision: https://reviews.llvm.org/D98794
2021-04-15 20:58:54 +02:00
|
|
|
MaybeAlign MemAlign = Arg.Alignment;
|
Reland [X86] Codegen for preallocated
See https://reviews.llvm.org/D74651 for the preallocated IR constructs
and LangRef changes.
In X86TargetLowering::LowerCall(), if a call is preallocated, record
each argument's offset from the stack pointer and the total stack
adjustment. Associate the call Value with an integer index. Store the
info in X86MachineFunctionInfo with the integer index as the key.
This adds two new target independent ISDOpcodes and two new target
dependent Opcodes corresponding to @llvm.call.preallocated.{setup,arg}.
The setup ISelDAG node takes in a chain and outputs a chain and a
SrcValue of the preallocated call Value. It is lowered to a target
dependent node with the SrcValue replaced with the integer index key by
looking in X86MachineFunctionInfo. In
X86TargetLowering::EmitInstrWithCustomInserter() this is lowered to an
%esp adjustment, the exact amount determined by looking in
X86MachineFunctionInfo with the integer index key.
The arg ISelDAG node takes in a chain, a SrcValue of the preallocated
call Value, and the arg index int constant. It produces a chain and the
pointer fo the arg. It is lowered to a target dependent node with the
SrcValue replaced with the integer index key by looking in
X86MachineFunctionInfo. In
X86TargetLowering::EmitInstrWithCustomInserter() this is lowered to a
lea of the stack pointer plus an offset determined by looking in
X86MachineFunctionInfo with the integer index key.
Force any function containing a preallocated call to use the frame
pointer.
Does not yet handle a setup without a call, or a conditional call.
Does not yet handle musttail. That requires a LangRef change first.
Tried to look at all references to inalloca and see if they apply to
preallocated. I've made preallocated versions of tests testing inalloca
whenever possible and when they make sense (e.g. not alloca related,
inalloca edge cases).
Aside from the tests added here, I checked that this codegen produces
correct code for something like
```
struct A {
A();
A(A&&);
~A();
};
void bar() {
foo(foo(foo(foo(foo(A(), 4), 5), 6), 7), 8);
}
```
by replacing the inalloca version of the .ll file with the appropriate
preallocated code. Running the executable produces the same results as
using the current inalloca implementation.
Reverted due to unexpectedly passing tests, added REQUIRES: asserts for reland.
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77689
2020-03-16 20:32:36 +01:00
|
|
|
if (Arg.IsByVal || Arg.IsInAlloca || Arg.IsPreallocated) {
|
2021-07-07 23:50:30 +02:00
|
|
|
unsigned FrameSize = DL.getTypeAllocSize(Arg.IndirectType);
|
2019-05-30 20:48:23 +02:00
|
|
|
|
|
|
|
// For ByVal, alignment should come from FE. BE will guess if this info
|
|
|
|
// is not there, but there are cases it cannot get right.
|
[clang][AArch64] Correctly align HFA arguments when passed on the stack
When we pass a AArch64 Homogeneous Floating-Point
Aggregate (HFA) argument with increased alignment
requirements, for example
struct S {
__attribute__ ((__aligned__(16))) double v[4];
};
Clang uses `[4 x double]` for the parameter, which is passed
on the stack at alignment 8, whereas it should be at
alignment 16, following Rule C.4 in
AAPCS (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#642parameter-passing-rules)
Currently we don't have a way to express in LLVM IR the
alignment requirements of the function arguments. The align
attribute is applicable to pointers only, and only for some
special ways of passing arguments (e..g byval). When
implementing AAPCS32/AAPCS64, clang resorts to dubious hacks
of coercing to types, which naturally have the needed
alignment. We don't have enough types to cover all the
cases, though.
This patch introduces a new use of the stackalign attribute
to control stack slot alignment, when and if an argument is
passed in memory.
The attribute align is left as an optimizer hint - it still
applies to pointer types only and pertains to the content of
the pointer, whereas the alignment of the pointer itself is
determined by the stackalign attribute.
For byval arguments, the stackalign attribute assumes the
role, previously perfomed by align, falling back to align if
stackalign` is absent.
On the clang side, when passing arguments using the "direct"
style (cf. `ABIArgInfo::Kind`), now we can optionally
specify an alignment, which is emitted as the new
`stackalign` attribute.
Patch by Momchil Velikov and Lucas Prates.
Differential Revision: https://reviews.llvm.org/D98794
2021-04-15 20:58:54 +02:00
|
|
|
if (!MemAlign)
|
2021-07-07 23:50:30 +02:00
|
|
|
MemAlign = Align(TLI.getByValTypeAlignment(Arg.IndirectType, DL));
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setByValSize(FrameSize);
|
[clang][AArch64] Correctly align HFA arguments when passed on the stack
When we pass a AArch64 Homogeneous Floating-Point
Aggregate (HFA) argument with increased alignment
requirements, for example
struct S {
__attribute__ ((__aligned__(16))) double v[4];
};
Clang uses `[4 x double]` for the parameter, which is passed
on the stack at alignment 8, whereas it should be at
alignment 16, following Rule C.4 in
AAPCS (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#642parameter-passing-rules)
Currently we don't have a way to express in LLVM IR the
alignment requirements of the function arguments. The align
attribute is applicable to pointers only, and only for some
special ways of passing arguments (e..g byval). When
implementing AAPCS32/AAPCS64, clang resorts to dubious hacks
of coercing to types, which naturally have the needed
alignment. We don't have enough types to cover all the
cases, though.
This patch introduces a new use of the stackalign attribute
to control stack slot alignment, when and if an argument is
passed in memory.
The attribute align is left as an optimizer hint - it still
applies to pointer types only and pertains to the content of
the pointer, whereas the alignment of the pointer itself is
determined by the stackalign attribute.
For byval arguments, the stackalign attribute assumes the
role, previously perfomed by align, falling back to align if
stackalign` is absent.
On the clang side, when passing arguments using the "direct"
style (cf. `ABIArgInfo::Kind`), now we can optionally
specify an alignment, which is emitted as the new
`stackalign` attribute.
Patch by Momchil Velikov and Lucas Prates.
Differential Revision: https://reviews.llvm.org/D98794
2021-04-15 20:58:54 +02:00
|
|
|
} else if (!MemAlign) {
|
|
|
|
MemAlign = DL.getABITypeAlign(Arg.Ty);
|
2014-07-12 00:01:42 +02:00
|
|
|
}
|
[clang][AArch64] Correctly align HFA arguments when passed on the stack
When we pass a AArch64 Homogeneous Floating-Point
Aggregate (HFA) argument with increased alignment
requirements, for example
struct S {
__attribute__ ((__aligned__(16))) double v[4];
};
Clang uses `[4 x double]` for the parameter, which is passed
on the stack at alignment 8, whereas it should be at
alignment 16, following Rule C.4 in
AAPCS (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#642parameter-passing-rules)
Currently we don't have a way to express in LLVM IR the
alignment requirements of the function arguments. The align
attribute is applicable to pointers only, and only for some
special ways of passing arguments (e..g byval). When
implementing AAPCS32/AAPCS64, clang resorts to dubious hacks
of coercing to types, which naturally have the needed
alignment. We don't have enough types to cover all the
cases, though.
This patch introduces a new use of the stackalign attribute
to control stack slot alignment, when and if an argument is
passed in memory.
The attribute align is left as an optimizer hint - it still
applies to pointer types only and pertains to the content of
the pointer, whereas the alignment of the pointer itself is
determined by the stackalign attribute.
For byval arguments, the stackalign attribute assumes the
role, previously perfomed by align, falling back to align if
stackalign` is absent.
On the clang side, when passing arguments using the "direct"
style (cf. `ABIArgInfo::Kind`), now we can optionally
specify an alignment, which is emitted as the new
`stackalign` attribute.
Patch by Momchil Velikov and Lucas Prates.
Differential Revision: https://reviews.llvm.org/D98794
2021-04-15 20:58:54 +02:00
|
|
|
Flags.setMemAlign(*MemAlign);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (Arg.IsNest)
|
2014-07-12 00:01:42 +02:00
|
|
|
Flags.setNest();
|
|
|
|
if (NeedsRegBlock)
|
|
|
|
Flags.setInConsecutiveRegs();
|
2020-04-02 17:10:30 +02:00
|
|
|
Flags.setOrigAlign(DL.getABITypeAlign(Arg.Ty));
|
2014-07-12 00:01:42 +02:00
|
|
|
CLI.OutVals.push_back(Arg.Val);
|
|
|
|
CLI.OutFlags.push_back(Flags);
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
if (!fastLowerCall(CLI))
|
2014-07-12 00:01:42 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Set all unused physreg defs as dead.
|
|
|
|
assert(CLI.Call && "No call instruction specified.");
|
|
|
|
CLI.Call->setPhysRegsDeadExcept(CLI.InRegs, TRI);
|
|
|
|
|
2020-04-13 01:47:06 +02:00
|
|
|
if (CLI.NumResultRegs && CLI.CB)
|
|
|
|
updateValueMap(CLI.CB, CLI.ResultReg, CLI.NumResultRegs);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
2019-04-25 01:02:48 +02:00
|
|
|
// Set labels for heapallocsite call.
|
2020-04-13 01:47:06 +02:00
|
|
|
if (CLI.CB)
|
|
|
|
if (MDNode *MD = CLI.CB->getMetadata("heapallocsite"))
|
2019-10-28 22:53:32 +01:00
|
|
|
CLI.Call->setHeapAllocMarker(*MF, MD);
|
2019-04-25 01:02:48 +02:00
|
|
|
|
2014-07-12 00:01:42 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::lowerCall(const CallInst *CI) {
|
2020-04-11 09:35:32 +02:00
|
|
|
FunctionType *FuncTy = CI->getFunctionType();
|
|
|
|
Type *RetTy = CI->getType();
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
ArgListTy Args;
|
|
|
|
ArgListEntry Entry;
|
2020-04-11 09:35:32 +02:00
|
|
|
Args.reserve(CI->arg_size());
|
2014-07-12 00:01:42 +02:00
|
|
|
|
2020-04-11 09:35:32 +02:00
|
|
|
for (auto i = CI->arg_begin(), e = CI->arg_end(); i != e; ++i) {
|
2014-07-12 00:01:42 +02:00
|
|
|
Value *V = *i;
|
|
|
|
|
|
|
|
// Skip empty types
|
|
|
|
if (V->getType()->isEmptyTy())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Entry.Val = V;
|
|
|
|
Entry.Ty = V->getType();
|
|
|
|
|
|
|
|
// Skip the first return-type Attribute to get to params.
|
2020-04-11 09:35:32 +02:00
|
|
|
Entry.setAttributes(CI, i - CI->arg_begin());
|
2014-07-12 00:01:42 +02:00
|
|
|
Args.push_back(Entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if target-independent constraints permit a tail call here.
|
2014-09-03 22:56:52 +02:00
|
|
|
// Target-dependent constraints are checked within fastLowerCall.
|
2014-07-12 00:01:42 +02:00
|
|
|
bool IsTailCall = CI->isTailCall();
|
2020-04-14 08:04:52 +02:00
|
|
|
if (IsTailCall && !isInTailCallPosition(*CI, TM))
|
2014-07-12 00:01:42 +02:00
|
|
|
IsTailCall = false;
|
2019-12-03 01:42:33 +01:00
|
|
|
if (IsTailCall && MF->getFunction()
|
|
|
|
.getFnAttribute("disable-tail-calls")
|
2021-03-24 21:45:04 +01:00
|
|
|
.getValueAsBool())
|
2019-12-03 01:42:33 +01:00
|
|
|
IsTailCall = false;
|
2014-07-12 00:01:42 +02:00
|
|
|
|
|
|
|
CallLoweringInfo CLI;
|
2020-04-28 05:15:59 +02:00
|
|
|
CLI.setCallee(RetTy, FuncTy, CI->getCalledOperand(), std::move(Args), *CI)
|
2014-09-03 20:46:45 +02:00
|
|
|
.setTailCall(IsTailCall);
|
2014-07-12 00:01:42 +02:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
return lowerCallTo(CLI);
|
2014-07-12 00:01:42 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectCall(const User *I) {
|
2011-04-26 19:18:34 +02:00
|
|
|
const CallInst *Call = cast<CallInst>(I);
|
|
|
|
|
|
|
|
// Handle simple inline asms.
|
2020-04-28 05:15:59 +02:00
|
|
|
if (const InlineAsm *IA = dyn_cast<InlineAsm>(Call->getCalledOperand())) {
|
2011-04-26 19:18:34 +02:00
|
|
|
// Don't attempt to handle constraints.
|
|
|
|
if (!IA->getConstraintString().empty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
unsigned ExtraInfo = 0;
|
|
|
|
if (IA->hasSideEffects())
|
|
|
|
ExtraInfo |= InlineAsm::Extra_HasSideEffects;
|
|
|
|
if (IA->isAlignStack())
|
|
|
|
ExtraInfo |= InlineAsm::Extra_IsAlignStack;
|
2020-06-13 09:16:58 +02:00
|
|
|
if (Call->isConvergent())
|
|
|
|
ExtraInfo |= InlineAsm::Extra_IsConvergent;
|
2019-10-06 01:21:17 +02:00
|
|
|
ExtraInfo |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
|
2011-04-26 19:18:34 +02:00
|
|
|
|
2020-06-13 09:16:58 +02:00
|
|
|
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::INLINEASM));
|
|
|
|
MIB.addExternalSymbol(IA->getAsmString().c_str());
|
|
|
|
MIB.addImm(ExtraInfo);
|
|
|
|
|
|
|
|
const MDNode *SrcLoc = Call->getMetadata("srcloc");
|
|
|
|
if (SrcLoc)
|
|
|
|
MIB.addMetadata(SrcLoc);
|
|
|
|
|
2011-04-26 19:18:34 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-07-11 22:42:12 +02:00
|
|
|
// Handle intrinsic function calls.
|
|
|
|
if (const auto *II = dyn_cast<IntrinsicInst>(Call))
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectIntrinsicCall(II);
|
2008-09-25 19:05:24 +02:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
return lowerCall(Call);
|
2014-07-11 22:42:12 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
|
2014-07-11 22:42:12 +02:00
|
|
|
switch (II->getIntrinsicID()) {
|
2014-09-03 20:46:45 +02:00
|
|
|
default:
|
|
|
|
break;
|
2014-07-11 22:42:12 +02:00
|
|
|
// At -O0 we don't care about the lifetime intrinsics.
|
2012-02-18 00:03:39 +01:00
|
|
|
case Intrinsic::lifetime_start:
|
|
|
|
case Intrinsic::lifetime_end:
|
2014-07-11 22:42:12 +02:00
|
|
|
// The donothing intrinsic does, well, nothing.
|
2012-07-06 19:33:39 +02:00
|
|
|
case Intrinsic::donothing:
|
Add an @llvm.sideeffect intrinsic
This patch implements Chandler's idea [0] for supporting languages that
require support for infinite loops with side effects, such as Rust, providing
part of a solution to bug 965 [1].
Specifically, it adds an `llvm.sideeffect()` intrinsic, which has no actual
effect, but which appears to optimization passes to have obscure side effects,
such that they don't optimize away loops containing it. It also teaches
several optimization passes to ignore this intrinsic, so that it doesn't
significantly impact optimization in most cases.
As discussed on llvm-dev [2], this patch is the first of two major parts.
The second part, to change LLVM's semantics to have defined behavior
on infinite loops by default, with a function attribute for opting into
potential-undefined-behavior, will be implemented and posted for review in
a separate patch.
[0] http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html
[1] https://bugs.llvm.org/show_bug.cgi?id=965
[2] http://lists.llvm.org/pipermail/llvm-dev/2017-October/118632.html
Differential Revision: https://reviews.llvm.org/D38336
llvm-svn: 317729
2017-11-08 22:59:51 +01:00
|
|
|
// Neither does the sideeffect intrinsic.
|
|
|
|
case Intrinsic::sideeffect:
|
2016-07-22 14:54:53 +02:00
|
|
|
// Neither does the assume intrinsic; it's also OK not to codegen its operand.
|
|
|
|
case Intrinsic::assume:
|
2021-01-16 09:14:18 +01:00
|
|
|
// Neither does the llvm.experimental.noalias.scope.decl intrinsic
|
|
|
|
case Intrinsic::experimental_noalias_scope_decl:
|
2012-02-18 00:03:39 +01:00
|
|
|
return true;
|
2009-02-13 03:16:35 +01:00
|
|
|
case Intrinsic::dbg_declare: {
|
2014-07-11 22:42:12 +02:00
|
|
|
const DbgDeclareInst *DI = cast<DbgDeclareInst>(II);
|
2015-04-21 20:24:23 +02:00
|
|
|
assert(DI->getVariable() && "Missing variable");
|
|
|
|
if (!FuncInfo.MF->getMMI().hasDebugInfo()) {
|
2020-02-13 23:38:42 +01:00
|
|
|
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI
|
|
|
|
<< " (!hasDebugInfo)\n");
|
2009-07-03 00:43:26 +02:00
|
|
|
return true;
|
2012-03-15 22:33:44 +01:00
|
|
|
}
|
2009-02-13 03:16:35 +01:00
|
|
|
|
2010-04-15 03:51:59 +02:00
|
|
|
const Value *Address = DI->getAddress();
|
2012-03-15 22:33:47 +01:00
|
|
|
if (!Address || isa<UndefValue>(Address)) {
|
2020-02-13 23:38:42 +01:00
|
|
|
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI
|
|
|
|
<< " (bad/undef address)\n");
|
2010-02-06 03:26:02 +01:00
|
|
|
return true;
|
2012-03-15 22:33:44 +01:00
|
|
|
}
|
2010-09-14 22:29:31 +02:00
|
|
|
|
2017-05-09 18:02:20 +02:00
|
|
|
// Byval arguments with frame indices were already handled after argument
|
|
|
|
// lowering and before isel.
|
|
|
|
const auto *Arg =
|
|
|
|
dyn_cast<Argument>(Address->stripInBoundsConstantOffsets());
|
|
|
|
if (Arg && FuncInfo.getArgumentFrameIndex(Arg) != INT_MAX)
|
|
|
|
return true;
|
|
|
|
|
2013-06-16 22:34:15 +02:00
|
|
|
Optional<MachineOperand> Op;
|
2020-04-08 16:57:11 +02:00
|
|
|
if (Register Reg = lookUpRegForValue(Address))
|
2017-05-09 18:02:20 +02:00
|
|
|
Op = MachineOperand::CreateReg(Reg, false);
|
2012-03-20 02:07:58 +01:00
|
|
|
|
2012-03-30 02:02:55 +02:00
|
|
|
// If we have a VLA that has a "use" in a metadata node that's then used
|
|
|
|
// here but it has no other uses, then we have a problem. E.g.,
|
|
|
|
//
|
|
|
|
// int foo (const int *x) {
|
|
|
|
// char a[*x];
|
|
|
|
// return 0;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// If we assign 'a' a vreg and fast isel later on has to use the selection
|
|
|
|
// DAG isel, it will want to copy the value to the vreg. However, there are
|
|
|
|
// no uses, which goes counter to what selection DAG isel expects.
|
2013-06-16 22:34:15 +02:00
|
|
|
if (!Op && !Address->use_empty() && isa<Instruction>(Address) &&
|
2012-03-20 02:07:58 +01:00
|
|
|
(!isa<AllocaInst>(Address) ||
|
|
|
|
!FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(Address))))
|
2013-06-16 22:34:15 +02:00
|
|
|
Op = MachineOperand::CreateReg(FuncInfo.InitializeRegForValue(Address),
|
2013-09-19 00:08:59 +02:00
|
|
|
false);
|
2013-06-16 22:34:15 +02:00
|
|
|
|
2013-09-19 00:08:59 +02:00
|
|
|
if (Op) {
|
2015-04-03 21:20:26 +02:00
|
|
|
assert(DI->getVariable()->isValidLocationForIntrinsic(DbgLoc) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
[DebugInfo] Make sure all DBG_VALUEs' reguse operands have IsDebug property
Summary:
In some cases, these operands lacked the IsDebug property, which is meant to signal that
they should not affect codegen. This patch adds a check for this property in the
MachineVerifier and adds it where it was missing.
This includes refactorings to use MachineInstrBuilder construction functions instead of
manually setting up the intrinsic everywhere.
Patch by: JesperAntonsson
Reviewers: aprantl, rnk, echristo, javed.absar
Reviewed By: aprantl
Subscribers: qcolombet, sdardis, nemanjai, JDevlieghere, atanasyan, llvm-commits
Differential Revision: https://reviews.llvm.org/D48319
llvm-svn: 335214
2018-06-21 12:03:34 +02:00
|
|
|
// A dbg.declare describes the address of a source variable, so lower it
|
|
|
|
// into an indirect DBG_VALUE.
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
2020-02-05 18:27:44 +01:00
|
|
|
TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ true,
|
|
|
|
*Op, DI->getVariable(), DI->getExpression());
|
2013-09-19 00:08:59 +02:00
|
|
|
} else {
|
2012-03-20 02:07:53 +01:00
|
|
|
// We can't yet handle anything else here because it would require
|
|
|
|
// generating code, thus altering codegen because of debug info.
|
2020-02-13 23:38:42 +01:00
|
|
|
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI
|
|
|
|
<< " (no materialized reg for address)\n");
|
2013-09-19 00:08:59 +02:00
|
|
|
}
|
2008-09-25 19:05:24 +02:00
|
|
|
return true;
|
2009-02-13 03:16:35 +01:00
|
|
|
}
|
2010-02-26 21:01:55 +01:00
|
|
|
case Intrinsic::dbg_value: {
|
2010-04-07 03:15:14 +02:00
|
|
|
// This form of DBG_VALUE is target-independent.
|
2014-07-11 22:42:12 +02:00
|
|
|
const DbgValueInst *DI = cast<DbgValueInst>(II);
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
|
2010-04-15 03:51:59 +02:00
|
|
|
const Value *V = DI->getValue();
|
2015-04-03 21:20:26 +02:00
|
|
|
assert(DI->getVariable()->isValidLocationForIntrinsic(DbgLoc) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
2021-05-20 17:33:38 +02:00
|
|
|
if (!V || isa<UndefValue>(V) || DI->hasArgList()) {
|
|
|
|
// DI is either undef or cannot produce a valid DBG_VALUE, so produce an
|
|
|
|
// undef DBG_VALUE to terminate any prior location.
|
2017-08-02 00:37:35 +02:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, false, 0U,
|
|
|
|
DI->getVariable(), DI->getExpression());
|
2014-09-03 20:46:45 +02:00
|
|
|
} else if (const auto *CI = dyn_cast<ConstantInt>(V)) {
|
2011-06-24 22:46:11 +02:00
|
|
|
if (CI->getBitWidth() > 64)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addCImm(CI)
|
2020-02-05 18:27:44 +01:00
|
|
|
.addImm(0U)
|
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
Note: I accidentally committed a bogus older version of this patch previously.
llvm-svn: 218787
2014-10-01 20:55:02 +02:00
|
|
|
.addMetadata(DI->getVariable())
|
|
|
|
.addMetadata(DI->getExpression());
|
2012-07-06 19:44:22 +02:00
|
|
|
else
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(CI->getZExtValue())
|
2020-02-05 18:27:44 +01:00
|
|
|
.addImm(0U)
|
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
Note: I accidentally committed a bogus older version of this patch previously.
llvm-svn: 218787
2014-10-01 20:55:02 +02:00
|
|
|
.addMetadata(DI->getVariable())
|
|
|
|
.addMetadata(DI->getExpression());
|
2014-09-03 20:46:45 +02:00
|
|
|
} else if (const auto *CF = dyn_cast<ConstantFP>(V)) {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addFPImm(CF)
|
2020-02-05 18:27:44 +01:00
|
|
|
.addImm(0U)
|
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
Note: I accidentally committed a bogus older version of this patch previously.
llvm-svn: 218787
2014-10-01 20:55:02 +02:00
|
|
|
.addMetadata(DI->getVariable())
|
|
|
|
.addMetadata(DI->getExpression());
|
2020-04-08 16:57:11 +02:00
|
|
|
} else if (Register Reg = lookUpRegForValue(V)) {
|
2013-09-17 01:29:03 +02:00
|
|
|
// FIXME: This does not handle register-indirect values at offset 0.
|
2017-07-28 22:21:02 +02:00
|
|
|
bool IsIndirect = false;
|
2017-07-29 01:00:45 +02:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, IsIndirect, Reg,
|
2017-07-28 22:21:02 +02:00
|
|
|
DI->getVariable(), DI->getExpression());
|
2010-02-26 21:01:55 +01:00
|
|
|
} else {
|
2020-01-16 23:02:09 +01:00
|
|
|
// We don't know how to handle other cases, so we drop.
|
2018-05-14 14:53:11 +02:00
|
|
|
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
|
2010-11-23 04:31:01 +01:00
|
|
|
}
|
2010-02-26 21:01:55 +01:00
|
|
|
return true;
|
|
|
|
}
|
2018-08-18 16:55:34 +02:00
|
|
|
case Intrinsic::dbg_label: {
|
|
|
|
const DbgLabelInst *DI = cast<DbgLabelInst>(II);
|
|
|
|
assert(DI->getLabel() && "Missing label");
|
|
|
|
if (!FuncInfo.MF->getMMI().hasDebugInfo()) {
|
|
|
|
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::DBG_LABEL)).addMetadata(DI->getLabel());
|
|
|
|
return true;
|
|
|
|
}
|
2019-10-14 18:15:14 +02:00
|
|
|
case Intrinsic::objectsize:
|
|
|
|
llvm_unreachable("llvm.objectsize.* should have been lowered already");
|
|
|
|
|
|
|
|
case Intrinsic::is_constant:
|
|
|
|
llvm_unreachable("llvm.is.constant.* should have been lowered already");
|
|
|
|
|
2018-05-03 13:03:01 +02:00
|
|
|
case Intrinsic::launder_invariant_group:
|
Implement strip.invariant.group
Summary:
This patch introduce new intrinsic -
strip.invariant.group that was described in the
RFC: Devirtualization v2
Reviewers: rsmith, hfinkel, nlopes, sanjoy, amharc, kuhar
Subscribers: arsenm, nhaehnle, JDevlieghere, hiraditya, xbolva00, llvm-commits
Differential Revision: https://reviews.llvm.org/D47103
Co-authored-by: Krzysztof Pszeniczny <krzysztof.pszeniczny@gmail.com>
llvm-svn: 336073
2018-07-02 06:49:30 +02:00
|
|
|
case Intrinsic::strip_invariant_group:
|
2013-03-07 21:42:17 +01:00
|
|
|
case Intrinsic::expect: {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = getRegForValue(II->getArgOperand(0));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!ResultReg)
|
2013-03-11 22:44:37 +01:00
|
|
|
return false;
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(II, ResultReg);
|
2013-03-07 22:38:33 +01:00
|
|
|
return true;
|
2013-03-07 21:42:17 +01:00
|
|
|
}
|
2014-07-02 00:25:49 +02:00
|
|
|
case Intrinsic::experimental_stackmap:
|
2021-04-21 00:37:49 +02:00
|
|
|
return selectStackmap(II);
|
2014-07-12 00:19:02 +02:00
|
|
|
case Intrinsic::experimental_patchpoint_void:
|
|
|
|
case Intrinsic::experimental_patchpoint_i64:
|
2021-04-21 00:37:49 +02:00
|
|
|
return selectPatchpoint(II);
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 07:45:21 +02:00
|
|
|
|
|
|
|
case Intrinsic::xray_customevent:
|
2021-04-21 00:37:49 +02:00
|
|
|
return selectXRayCustomEvent(II);
|
2018-04-17 23:30:29 +02:00
|
|
|
case Intrinsic::xray_typedevent:
|
2021-04-21 00:37:49 +02:00
|
|
|
return selectXRayTypedEvent(II);
|
2008-09-25 19:05:24 +02:00
|
|
|
}
|
2010-04-13 19:07:06 +02:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
return fastLowerIntrinsicCall(II);
|
2008-09-25 19:05:24 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectCast(const User *I, unsigned Opcode) {
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType());
|
|
|
|
EVT DstVT = TLI.getValueType(DL, I->getType());
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
if (SrcVT == MVT::Other || !SrcVT.isSimple() || DstVT == MVT::Other ||
|
|
|
|
!DstVT.isSimple())
|
2008-08-27 01:46:32 +02:00
|
|
|
// Unhandled type. Halt "fast" selection and bail.
|
|
|
|
return false;
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2011-05-26 01:49:02 +02:00
|
|
|
// Check if the destination type is legal.
|
2009-03-14 00:53:06 +01:00
|
|
|
if (!TLI.isTypeLegal(DstVT))
|
2011-05-26 01:49:02 +02:00
|
|
|
return false;
|
2009-03-14 00:53:06 +01:00
|
|
|
|
2011-05-26 01:49:02 +02:00
|
|
|
// Check if the source operand is legal.
|
2009-03-14 00:53:06 +01:00
|
|
|
if (!TLI.isTypeLegal(SrcVT))
|
2011-05-26 01:49:02 +02:00
|
|
|
return false;
|
2009-03-14 00:53:06 +01:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register InputReg = getRegForValue(I->getOperand(0));
|
2008-08-27 01:46:32 +02:00
|
|
|
if (!InputReg)
|
|
|
|
// Unhandled operand. Halt "fast" selection and bail.
|
|
|
|
return false;
|
2009-03-13 21:42:20 +01:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = fastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(),
|
2021-03-09 21:04:03 +01:00
|
|
|
Opcode, InputReg);
|
2008-08-27 01:46:32 +02:00
|
|
|
if (!ResultReg)
|
|
|
|
return false;
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2008-08-27 01:46:32 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectBitCast(const User *I) {
|
2008-08-27 20:10:19 +02:00
|
|
|
// If the bitcast doesn't change the type, just use the operand value.
|
|
|
|
if (I->getType() == I->getOperand(0)->getType()) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Reg = getRegForValue(I->getOperand(0));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Reg)
|
2008-08-27 22:41:38 +02:00
|
|
|
return false;
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, Reg);
|
2008-08-27 20:10:19 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-11-23 04:31:01 +01:00
|
|
|
// Bitcasts of other values become reg-reg copies or BITCAST operators.
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT SrcEVT = TLI.getValueType(DL, I->getOperand(0)->getType());
|
|
|
|
EVT DstEVT = TLI.getValueType(DL, I->getType());
|
2012-12-17 15:30:06 +01:00
|
|
|
if (SrcEVT == MVT::Other || DstEVT == MVT::Other ||
|
|
|
|
!TLI.isTypeLegal(SrcEVT) || !TLI.isTypeLegal(DstEVT))
|
2008-08-27 01:46:32 +02:00
|
|
|
// Unhandled type. Halt "fast" selection and bail.
|
|
|
|
return false;
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2012-12-17 15:30:06 +01:00
|
|
|
MVT SrcVT = SrcEVT.getSimpleVT();
|
|
|
|
MVT DstVT = DstEVT.getSimpleVT();
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Op0 = getRegForValue(I->getOperand(0));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Op0) // Unhandled operand. Halt "fast" selection and bail.
|
2008-08-27 01:46:32 +02:00
|
|
|
return false;
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2008-08-27 20:10:19 +02:00
|
|
|
// First, try to perform the bitcast by inserting a reg-reg copy.
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg;
|
2012-12-13 07:34:11 +01:00
|
|
|
if (SrcVT == DstVT) {
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *SrcClass = TLI.getRegClassFor(SrcVT);
|
|
|
|
const TargetRegisterClass *DstClass = TLI.getRegClassFor(DstVT);
|
2010-07-11 07:16:54 +02:00
|
|
|
// Don't attempt a cross-class copy. It will likely fail.
|
|
|
|
if (SrcClass == DstClass) {
|
|
|
|
ResultReg = createResultReg(DstClass);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(Op0);
|
2010-07-11 07:16:54 +02:00
|
|
|
}
|
2008-08-27 20:10:19 +02:00
|
|
|
}
|
2010-11-23 04:31:01 +01:00
|
|
|
|
|
|
|
// If the reg-reg copy failed, select a BITCAST opcode.
|
2008-08-27 20:10:19 +02:00
|
|
|
if (!ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
ResultReg = fastEmit_r(SrcVT, DstVT, ISD::BITCAST, Op0);
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2008-08-27 20:10:19 +02:00
|
|
|
if (!ResultReg)
|
2008-08-27 01:46:32 +02:00
|
|
|
return false;
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2008-08-27 01:46:32 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
[SelDag] Add FREEZE
Summary:
- Add FREEZE node to SelDag
- Lower FreezeInst (in IR) to FREEZE node
- Add Legalization for FREEZE node
Reviewers: qcolombet, bogner, efriedma, lebedev.ri, nlopes, craig.topper, arsenm
Reviewed By: lebedev.ri
Subscribers: wdng, xbolva00, Petar.Avramovic, liuz, lkail, dylanmckay, hiraditya, Jim, arsenm, craig.topper, RKSimon, spatel, lebedev.ri, regehr, trentxintong, nlopes, mkuper, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D29014
2020-03-23 05:03:13 +01:00
|
|
|
bool FastISel::selectFreeze(const User *I) {
|
|
|
|
Register Reg = getRegForValue(I->getOperand(0));
|
|
|
|
if (!Reg)
|
|
|
|
// Unhandled operand.
|
|
|
|
return false;
|
|
|
|
|
|
|
|
EVT ETy = TLI.getValueType(DL, I->getOperand(0)->getType());
|
|
|
|
if (ETy == MVT::Other || !TLI.isTypeLegal(ETy))
|
|
|
|
// Unhandled type, bail out.
|
|
|
|
return false;
|
|
|
|
|
|
|
|
MVT Ty = ETy.getSimpleVT();
|
|
|
|
const TargetRegisterClass *TyRegClass = TLI.getRegClassFor(Ty);
|
|
|
|
Register ResultReg = createResultReg(TyRegClass);
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(Reg);
|
|
|
|
|
|
|
|
updateValueMap(I, ResultReg);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-14 19:33:18 +01:00
|
|
|
// Remove local value instructions starting from the instruction after
|
|
|
|
// SavedLastLocalValue to the current function insert point.
|
|
|
|
void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue)
|
|
|
|
{
|
|
|
|
MachineInstr *CurLastLocalValue = getLastLocalValue();
|
|
|
|
if (CurLastLocalValue != SavedLastLocalValue) {
|
2018-07-30 21:41:25 +02:00
|
|
|
// Find the first local value instruction to be deleted.
|
2015-12-14 19:33:18 +01:00
|
|
|
// This is the instruction after SavedLastLocalValue if it is non-NULL.
|
|
|
|
// Otherwise it's the first instruction in the block.
|
|
|
|
MachineBasicBlock::iterator FirstDeadInst(SavedLastLocalValue);
|
|
|
|
if (SavedLastLocalValue)
|
|
|
|
++FirstDeadInst;
|
|
|
|
else
|
|
|
|
FirstDeadInst = FuncInfo.MBB->getFirstNonPHI();
|
|
|
|
setLastLocalValue(SavedLastLocalValue);
|
|
|
|
removeDeadCode(FirstDeadInst, FuncInfo.InsertPt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
bool FastISel::selectInstruction(const Instruction *I) {
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
// Flush the local value map before starting each instruction.
|
|
|
|
// This improves locality and debugging, and can reduce spills.
|
|
|
|
// Reuse of values across IR instructions is relatively uncommon.
|
|
|
|
flushLocalValueMap();
|
|
|
|
|
2015-12-14 19:33:18 +01:00
|
|
|
MachineInstr *SavedLastLocalValue = getLastLocalValue();
|
2010-04-23 17:29:50 +02:00
|
|
|
// Just before the terminator instruction, insert instructions to
|
|
|
|
// feed PHI nodes in successor blocks.
|
2018-08-26 11:51:22 +02:00
|
|
|
if (I->isTerminator()) {
|
2015-12-14 19:33:18 +01:00
|
|
|
if (!handlePHINodesInSuccessorBlocks(I->getParent())) {
|
|
|
|
// PHI node handling may have generated local value instructions,
|
|
|
|
// even though it failed to handle all PHI nodes.
|
2018-07-30 21:41:25 +02:00
|
|
|
// We remove these instructions because SelectionDAGISel will generate
|
2015-12-14 19:33:18 +01:00
|
|
|
// them again.
|
|
|
|
removeDeadLocalValueCode(SavedLastLocalValue);
|
2010-04-23 17:29:50 +02:00
|
|
|
return false;
|
2015-12-14 19:33:18 +01:00
|
|
|
}
|
2016-04-05 20:13:16 +02:00
|
|
|
}
|
2010-04-23 17:29:50 +02:00
|
|
|
|
2016-03-22 01:59:13 +01:00
|
|
|
// FastISel does not handle any operand bundles except OB_funclet.
|
2020-04-11 09:35:32 +02:00
|
|
|
if (auto *Call = dyn_cast<CallBase>(I))
|
|
|
|
for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i)
|
|
|
|
if (Call->getOperandBundleAt(i).getTagID() != LLVMContext::OB_funclet)
|
2016-03-22 01:59:13 +01:00
|
|
|
return false;
|
|
|
|
|
2014-02-18 23:05:46 +01:00
|
|
|
DbgLoc = I->getDebugLoc();
|
2010-04-20 02:48:35 +02:00
|
|
|
|
2014-09-08 22:24:10 +02:00
|
|
|
SavedInsertPt = FuncInfo.InsertPt;
|
2011-11-29 20:40:47 +01:00
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *Call = dyn_cast<CallInst>(I)) {
|
2012-08-03 06:06:28 +02:00
|
|
|
const Function *F = Call->getCalledFunction();
|
[Analysis] Add LibFunc_ prefix to enums in TargetLibraryInfo. (NFC)
Summary:
The LibFunc::Func enum holds enumerators named for libc functions.
Unfortunately, there are real situations, including libc implementations, where
function names are actually macros (musl uses "#define fopen64 fopen", for
example; any other transitively visible macro would have similar effects).
Strictly speaking, a conforming C++ Standard Library should provide any such
macros as functions instead (via <cstdio>). However, there are some "library"
functions which are not part of the standard, and thus not subject to this
rule (fopen64, for example). So, in order to be both portable and consistent,
the enum should not use the bare function names.
The old enum naming used a namespace LibFunc and an enum Func, with bare
enumerators. This patch changes LibFunc to be an enum with enumerators prefixed
with "LibFFunc_". (Unfortunately, a scoped enum is not sufficient to override
macros.)
There are additional changes required in clang.
Reviewers: rsmith
Subscribers: mehdi_amini, mzolotukhin, nemanjai, llvm-commits
Differential Revision: https://reviews.llvm.org/D28476
llvm-svn: 292848
2017-01-24 00:16:46 +01:00
|
|
|
LibFunc Func;
|
2014-04-15 23:30:06 +02:00
|
|
|
|
|
|
|
// As a special case, don't handle calls to builtin library functions that
|
|
|
|
// may be translated directly to target instructions.
|
2012-08-03 06:06:28 +02:00
|
|
|
if (F && !F->hasLocalLinkage() && F->hasName() &&
|
|
|
|
LibInfo->getLibFunc(F->getName(), Func) &&
|
2012-08-03 23:26:24 +02:00
|
|
|
LibInfo->hasOptimizedCodeGen(Func))
|
2012-08-03 06:06:28 +02:00
|
|
|
return false;
|
2014-04-15 23:30:06 +02:00
|
|
|
|
2015-12-16 01:08:18 +01:00
|
|
|
// Don't handle Intrinsic::trap if a trap function is specified.
|
2014-04-15 23:30:06 +02:00
|
|
|
if (F && F->getIntrinsicID() == Intrinsic::trap &&
|
2015-07-03 00:13:27 +02:00
|
|
|
Call->hasFnAttr("trap-func-name"))
|
2014-04-15 23:30:06 +02:00
|
|
|
return false;
|
2012-08-03 06:06:28 +02:00
|
|
|
}
|
|
|
|
|
2009-12-05 02:27:58 +01:00
|
|
|
// First, try doing target-independent selection.
|
2014-09-02 23:07:44 +02:00
|
|
|
if (!SkipTargetIndependentISel) {
|
2014-09-03 20:46:45 +02:00
|
|
|
if (selectOperator(I, I->getOpcode())) {
|
2014-09-02 23:07:44 +02:00
|
|
|
++NumFastIselSuccessIndependent;
|
|
|
|
DbgLoc = DebugLoc();
|
|
|
|
return true;
|
|
|
|
}
|
2014-09-08 22:24:10 +02:00
|
|
|
// Remove dead code.
|
|
|
|
recomputeInsertPt();
|
|
|
|
if (SavedInsertPt != FuncInfo.InsertPt)
|
|
|
|
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
|
2014-09-02 23:07:44 +02:00
|
|
|
SavedInsertPt = FuncInfo.InsertPt;
|
|
|
|
}
|
|
|
|
// Next, try calling the target to attempt to handle the instruction.
|
2014-09-03 22:56:52 +02:00
|
|
|
if (fastSelectInstruction(I)) {
|
2014-09-02 23:07:44 +02:00
|
|
|
++NumFastIselSuccessTarget;
|
2014-02-18 23:05:46 +01:00
|
|
|
DbgLoc = DebugLoc();
|
2009-12-05 02:27:58 +01:00
|
|
|
return true;
|
2010-04-20 02:48:35 +02:00
|
|
|
}
|
2014-09-08 22:24:10 +02:00
|
|
|
// Remove dead code.
|
|
|
|
recomputeInsertPt();
|
|
|
|
if (SavedInsertPt != FuncInfo.InsertPt)
|
|
|
|
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
|
2009-12-05 02:27:58 +01:00
|
|
|
|
2014-02-18 23:05:46 +01:00
|
|
|
DbgLoc = DebugLoc();
|
2014-08-28 04:06:55 +02:00
|
|
|
// Undo phi node updates, because they will be added again by SelectionDAG.
|
2018-08-26 11:51:22 +02:00
|
|
|
if (I->isTerminator()) {
|
2018-07-30 21:41:25 +02:00
|
|
|
// PHI node handling may have generated local value instructions.
|
2015-12-14 19:33:18 +01:00
|
|
|
// We remove them because SelectionDAGISel will generate them again.
|
|
|
|
removeDeadLocalValueCode(SavedLastLocalValue);
|
2014-08-28 04:06:55 +02:00
|
|
|
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
|
2015-12-14 19:33:18 +01:00
|
|
|
}
|
2009-12-05 02:27:58 +01:00
|
|
|
return false;
|
2008-09-05 20:18:20 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
/// Emit an unconditional branch to the given block, unless it is the immediate
|
|
|
|
/// (fall-through) successor, and update the CFG.
|
2016-06-12 17:39:02 +02:00
|
|
|
void FastISel::fastEmitBranch(MachineBasicBlock *MSucc,
|
|
|
|
const DebugLoc &DbgLoc) {
|
2019-09-20 15:22:59 +02:00
|
|
|
if (FuncInfo.MBB->getBasicBlock()->sizeWithoutDebug() > 1 &&
|
2013-02-11 02:27:15 +01:00
|
|
|
FuncInfo.MBB->isLayoutSuccessor(MSucc)) {
|
2019-09-20 15:22:59 +02:00
|
|
|
// For more accurate line information if this is the only non-debug
|
|
|
|
// instruction in the block then emit it, otherwise we have the
|
|
|
|
// unconditional fall-through case, which needs no instructions.
|
2008-10-03 00:15:21 +02:00
|
|
|
} else {
|
|
|
|
// The unconditional branch case.
|
2016-09-14 19:24:15 +02:00
|
|
|
TII.insertBranch(*FuncInfo.MBB, MSucc, nullptr,
|
2014-02-18 23:05:46 +01:00
|
|
|
SmallVector<MachineOperand, 0>(), DbgLoc);
|
2008-10-03 00:15:21 +02:00
|
|
|
}
|
Create a new interface addSuccessorWithoutWeight(MBB*) in MBB to add successors when optimization is disabled.
When optimization is disabled, edge weights that are stored in MBB won't be used so that we don't have to store them. Currently, this is done by adding successors with default weight 0, and if all successors have default weights, the weight list will be empty. But that the weight list is empty doesn't mean disabled optimization (as is stated several times in MachineBasicBlock.cpp): it may also mean all successors just have default weights.
We should discourage using default weights when adding successors, because it is very easy for users to forget update the correct edge weights instead of using default ones (one exception is that the MBB only has one successor). In order to detect such usages, it is better to differentiate using default weights from the case when optimizations is disabled.
In this patch, a new interface addSuccessorWithoutWeight(MBB*) is created for when optimization is disabled. In this case, MBB will try to maintain an empty weight list, but it cannot guarantee this as for many uses of addSuccessor() whether optimization is disabled or not is not checked. But it can guarantee that if optimization is enabled, then the weight list always has the same size of the successor list.
Differential revision: http://reviews.llvm.org/D13963
llvm-svn: 251429
2015-10-27 18:59:36 +01:00
|
|
|
if (FuncInfo.BPI) {
|
2015-11-24 09:51:23 +01:00
|
|
|
auto BranchProbability = FuncInfo.BPI->getEdgeProbability(
|
Create a new interface addSuccessorWithoutWeight(MBB*) in MBB to add successors when optimization is disabled.
When optimization is disabled, edge weights that are stored in MBB won't be used so that we don't have to store them. Currently, this is done by adding successors with default weight 0, and if all successors have default weights, the weight list will be empty. But that the weight list is empty doesn't mean disabled optimization (as is stated several times in MachineBasicBlock.cpp): it may also mean all successors just have default weights.
We should discourage using default weights when adding successors, because it is very easy for users to forget update the correct edge weights instead of using default ones (one exception is that the MBB only has one successor). In order to detect such usages, it is better to differentiate using default weights from the case when optimizations is disabled.
In this patch, a new interface addSuccessorWithoutWeight(MBB*) is created for when optimization is disabled. In this case, MBB will try to maintain an empty weight list, but it cannot guarantee this as for many uses of addSuccessor() whether optimization is disabled or not is not checked. But it can guarantee that if optimization is enabled, then the weight list always has the same size of the successor list.
Differential revision: http://reviews.llvm.org/D13963
llvm-svn: 251429
2015-10-27 18:59:36 +01:00
|
|
|
FuncInfo.MBB->getBasicBlock(), MSucc->getBasicBlock());
|
2015-11-24 09:51:23 +01:00
|
|
|
FuncInfo.MBB->addSuccessor(MSucc, BranchProbability);
|
Create a new interface addSuccessorWithoutWeight(MBB*) in MBB to add successors when optimization is disabled.
When optimization is disabled, edge weights that are stored in MBB won't be used so that we don't have to store them. Currently, this is done by adding successors with default weight 0, and if all successors have default weights, the weight list will be empty. But that the weight list is empty doesn't mean disabled optimization (as is stated several times in MachineBasicBlock.cpp): it may also mean all successors just have default weights.
We should discourage using default weights when adding successors, because it is very easy for users to forget update the correct edge weights instead of using default ones (one exception is that the MBB only has one successor). In order to detect such usages, it is better to differentiate using default weights from the case when optimizations is disabled.
In this patch, a new interface addSuccessorWithoutWeight(MBB*) is created for when optimization is disabled. In this case, MBB will try to maintain an empty weight list, but it cannot guarantee this as for many uses of addSuccessor() whether optimization is disabled or not is not checked. But it can guarantee that if optimization is enabled, then the weight list always has the same size of the successor list.
Differential revision: http://reviews.llvm.org/D13963
llvm-svn: 251429
2015-10-27 18:59:36 +01:00
|
|
|
} else
|
2015-11-24 09:51:23 +01:00
|
|
|
FuncInfo.MBB->addSuccessorWithoutProb(MSucc);
|
2008-10-03 00:15:21 +02:00
|
|
|
}
|
|
|
|
|
2015-08-26 03:38:00 +02:00
|
|
|
void FastISel::finishCondBranch(const BasicBlock *BranchBB,
|
|
|
|
MachineBasicBlock *TrueMBB,
|
|
|
|
MachineBasicBlock *FalseMBB) {
|
2015-08-26 22:46:49 +02:00
|
|
|
// Add TrueMBB as successor unless it is equal to the FalseMBB: This can
|
|
|
|
// happen in degenerate IR and MachineIR forbids to have a block twice in the
|
|
|
|
// successor/predecessor lists.
|
Create a new interface addSuccessorWithoutWeight(MBB*) in MBB to add successors when optimization is disabled.
When optimization is disabled, edge weights that are stored in MBB won't be used so that we don't have to store them. Currently, this is done by adding successors with default weight 0, and if all successors have default weights, the weight list will be empty. But that the weight list is empty doesn't mean disabled optimization (as is stated several times in MachineBasicBlock.cpp): it may also mean all successors just have default weights.
We should discourage using default weights when adding successors, because it is very easy for users to forget update the correct edge weights instead of using default ones (one exception is that the MBB only has one successor). In order to detect such usages, it is better to differentiate using default weights from the case when optimizations is disabled.
In this patch, a new interface addSuccessorWithoutWeight(MBB*) is created for when optimization is disabled. In this case, MBB will try to maintain an empty weight list, but it cannot guarantee this as for many uses of addSuccessor() whether optimization is disabled or not is not checked. But it can guarantee that if optimization is enabled, then the weight list always has the same size of the successor list.
Differential revision: http://reviews.llvm.org/D13963
llvm-svn: 251429
2015-10-27 18:59:36 +01:00
|
|
|
if (TrueMBB != FalseMBB) {
|
|
|
|
if (FuncInfo.BPI) {
|
2015-11-24 09:51:23 +01:00
|
|
|
auto BranchProbability =
|
|
|
|
FuncInfo.BPI->getEdgeProbability(BranchBB, TrueMBB->getBasicBlock());
|
|
|
|
FuncInfo.MBB->addSuccessor(TrueMBB, BranchProbability);
|
Create a new interface addSuccessorWithoutWeight(MBB*) in MBB to add successors when optimization is disabled.
When optimization is disabled, edge weights that are stored in MBB won't be used so that we don't have to store them. Currently, this is done by adding successors with default weight 0, and if all successors have default weights, the weight list will be empty. But that the weight list is empty doesn't mean disabled optimization (as is stated several times in MachineBasicBlock.cpp): it may also mean all successors just have default weights.
We should discourage using default weights when adding successors, because it is very easy for users to forget update the correct edge weights instead of using default ones (one exception is that the MBB only has one successor). In order to detect such usages, it is better to differentiate using default weights from the case when optimizations is disabled.
In this patch, a new interface addSuccessorWithoutWeight(MBB*) is created for when optimization is disabled. In this case, MBB will try to maintain an empty weight list, but it cannot guarantee this as for many uses of addSuccessor() whether optimization is disabled or not is not checked. But it can guarantee that if optimization is enabled, then the weight list always has the same size of the successor list.
Differential revision: http://reviews.llvm.org/D13963
llvm-svn: 251429
2015-10-27 18:59:36 +01:00
|
|
|
} else
|
2015-11-24 09:51:23 +01:00
|
|
|
FuncInfo.MBB->addSuccessorWithoutProb(TrueMBB);
|
Create a new interface addSuccessorWithoutWeight(MBB*) in MBB to add successors when optimization is disabled.
When optimization is disabled, edge weights that are stored in MBB won't be used so that we don't have to store them. Currently, this is done by adding successors with default weight 0, and if all successors have default weights, the weight list will be empty. But that the weight list is empty doesn't mean disabled optimization (as is stated several times in MachineBasicBlock.cpp): it may also mean all successors just have default weights.
We should discourage using default weights when adding successors, because it is very easy for users to forget update the correct edge weights instead of using default ones (one exception is that the MBB only has one successor). In order to detect such usages, it is better to differentiate using default weights from the case when optimizations is disabled.
In this patch, a new interface addSuccessorWithoutWeight(MBB*) is created for when optimization is disabled. In this case, MBB will try to maintain an empty weight list, but it cannot guarantee this as for many uses of addSuccessor() whether optimization is disabled or not is not checked. But it can guarantee that if optimization is enabled, then the weight list always has the same size of the successor list.
Differential revision: http://reviews.llvm.org/D13963
llvm-svn: 251429
2015-10-27 18:59:36 +01:00
|
|
|
}
|
2015-08-26 03:38:00 +02:00
|
|
|
|
|
|
|
fastEmitBranch(FalseMBB, DbgLoc);
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
/// Emit an FNeg operation.
|
2019-05-07 06:25:24 +02:00
|
|
|
bool FastISel::selectFNeg(const User *I, const Value *In) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register OpReg = getRegForValue(In);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!OpReg)
|
|
|
|
return false;
|
2010-05-12 01:54:07 +02:00
|
|
|
|
2009-09-11 02:36:43 +02:00
|
|
|
// If the target has ISD::FNEG, use it.
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT VT = TLI.getValueType(DL, I->getType());
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = fastEmit_r(VT.getSimpleVT(), VT.getSimpleVT(), ISD::FNEG,
|
2021-03-09 21:04:03 +01:00
|
|
|
OpReg);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (ResultReg) {
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2009-09-11 02:36:43 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-09-11 02:34:46 +02:00
|
|
|
// Bitcast the value to integer, twiddle the sign bit with xor,
|
|
|
|
// and then bitcast it back to floating-point.
|
2014-09-03 20:46:45 +02:00
|
|
|
if (VT.getSizeInBits() > 64)
|
|
|
|
return false;
|
2009-09-11 02:34:46 +02:00
|
|
|
EVT IntVT = EVT::getIntegerVT(I->getContext(), VT.getSizeInBits());
|
|
|
|
if (!TLI.isTypeLegal(IntVT))
|
|
|
|
return false;
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register IntReg = fastEmit_r(VT.getSimpleVT(), IntVT.getSimpleVT(),
|
2021-03-09 21:04:03 +01:00
|
|
|
ISD::BITCAST, OpReg);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!IntReg)
|
2009-09-11 02:34:46 +02:00
|
|
|
return false;
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register IntResultReg = fastEmit_ri_(
|
2021-03-09 21:04:03 +01:00
|
|
|
IntVT.getSimpleVT(), ISD::XOR, IntReg,
|
2014-09-03 20:46:45 +02:00
|
|
|
UINT64_C(1) << (VT.getSizeInBits() - 1), IntVT.getSimpleVT());
|
|
|
|
if (!IntResultReg)
|
2009-09-11 02:34:46 +02:00
|
|
|
return false;
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
ResultReg = fastEmit_r(IntVT.getSimpleVT(), VT.getSimpleVT(), ISD::BITCAST,
|
2021-03-09 21:04:03 +01:00
|
|
|
IntResultReg);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!ResultReg)
|
2009-09-04 00:53:57 +02:00
|
|
|
return false;
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, ResultReg);
|
2009-09-04 00:53:57 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectExtractValue(const User *U) {
|
2011-05-16 22:27:46 +02:00
|
|
|
const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U);
|
2011-05-16 22:34:53 +02:00
|
|
|
if (!EVI)
|
2011-05-16 22:27:46 +02:00
|
|
|
return false;
|
|
|
|
|
2011-05-16 23:06:17 +02:00
|
|
|
// Make sure we only try to handle extracts with a legal result. But also
|
|
|
|
// allow i1 because it's easy.
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT RealVT = TLI.getValueType(DL, EVI->getType(), /*AllowUnknown=*/true);
|
2011-05-16 22:27:46 +02:00
|
|
|
if (!RealVT.isSimple())
|
|
|
|
return false;
|
|
|
|
MVT VT = RealVT.getSimpleVT();
|
2011-05-16 23:06:17 +02:00
|
|
|
if (!TLI.isTypeLegal(VT) && VT != MVT::i1)
|
2011-05-16 22:27:46 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
const Value *Op0 = EVI->getOperand(0);
|
2011-07-18 06:54:35 +02:00
|
|
|
Type *AggTy = Op0->getType();
|
2011-05-16 22:27:46 +02:00
|
|
|
|
|
|
|
// Get the base result register.
|
|
|
|
unsigned ResultReg;
|
2020-04-08 18:26:32 +02:00
|
|
|
DenseMap<const Value *, Register>::iterator I = FuncInfo.ValueMap.find(Op0);
|
2011-05-16 22:27:46 +02:00
|
|
|
if (I != FuncInfo.ValueMap.end())
|
|
|
|
ResultReg = I->second;
|
2011-06-06 07:46:34 +02:00
|
|
|
else if (isa<Instruction>(Op0))
|
2011-05-16 22:27:46 +02:00
|
|
|
ResultReg = FuncInfo.InitializeRegForValue(Op0);
|
2011-06-06 07:46:34 +02:00
|
|
|
else
|
|
|
|
return false; // fast-isel can't handle aggregate constants at the moment
|
2011-05-16 22:27:46 +02:00
|
|
|
|
|
|
|
// Get the actual result register, which is an offset from the base register.
|
2011-07-13 12:26:04 +02:00
|
|
|
unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->getIndices());
|
2011-05-16 22:27:46 +02:00
|
|
|
|
|
|
|
SmallVector<EVT, 4> AggValueVTs;
|
2015-07-09 03:57:34 +02:00
|
|
|
ComputeValueVTs(TLI, DL, AggTy, AggValueVTs);
|
2011-05-16 22:27:46 +02:00
|
|
|
|
|
|
|
for (unsigned i = 0; i < VTIndex; i++)
|
|
|
|
ResultReg += TLI.getNumRegisters(FuncInfo.Fn->getContext(), AggValueVTs[i]);
|
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(EVI, ResultReg);
|
2011-05-16 22:27:46 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::selectOperator(const User *I, unsigned Opcode) {
|
2008-09-05 20:18:20 +02:00
|
|
|
switch (Opcode) {
|
2009-06-05 00:49:04 +02:00
|
|
|
case Instruction::Add:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::ADD);
|
2009-06-05 00:49:04 +02:00
|
|
|
case Instruction::FAdd:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::FADD);
|
2009-06-05 00:49:04 +02:00
|
|
|
case Instruction::Sub:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::SUB);
|
2020-08-04 21:26:23 +02:00
|
|
|
case Instruction::FSub:
|
2019-05-07 06:25:24 +02:00
|
|
|
return selectBinaryOp(I, ISD::FSUB);
|
2009-06-05 00:49:04 +02:00
|
|
|
case Instruction::Mul:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::MUL);
|
2009-06-05 00:49:04 +02:00
|
|
|
case Instruction::FMul:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::FMUL);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::SDiv:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::SDIV);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::UDiv:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::UDIV);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::FDiv:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::FDIV);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::SRem:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::SREM);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::URem:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::UREM);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::FRem:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::FREM);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::Shl:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::SHL);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::LShr:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::SRL);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::AShr:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::SRA);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::And:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::AND);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::Or:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::OR);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::Xor:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBinaryOp(I, ISD::XOR);
|
2008-09-04 01:12:08 +02:00
|
|
|
|
2019-05-08 19:27:08 +02:00
|
|
|
case Instruction::FNeg:
|
|
|
|
return selectFNeg(I, I->getOperand(0));
|
|
|
|
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::GetElementPtr:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectGetElementPtr(I);
|
2008-09-04 01:12:08 +02:00
|
|
|
|
|
|
|
case Instruction::Br: {
|
2010-04-15 03:51:59 +02:00
|
|
|
const BranchInst *BI = cast<BranchInst>(I);
|
2008-09-04 01:12:08 +02:00
|
|
|
|
|
|
|
if (BI->isUnconditional()) {
|
2010-04-15 03:51:59 +02:00
|
|
|
const BasicBlock *LLVMSucc = BI->getSuccessor(0);
|
2010-07-07 18:29:44 +02:00
|
|
|
MachineBasicBlock *MSucc = FuncInfo.MBBMap[LLVMSucc];
|
2014-09-03 22:56:52 +02:00
|
|
|
fastEmitBranch(MSucc, BI->getDebugLoc());
|
2008-09-04 01:12:08 +02:00
|
|
|
return true;
|
2008-08-27 02:31:01 +02:00
|
|
|
}
|
2008-09-04 01:12:08 +02:00
|
|
|
|
|
|
|
// Conditional branches are not handed yet.
|
|
|
|
// Halt "fast" selection and bail.
|
|
|
|
return false;
|
2008-08-13 22:19:35 +02:00
|
|
|
}
|
|
|
|
|
2008-09-05 03:08:41 +02:00
|
|
|
case Instruction::Unreachable:
|
2015-10-09 03:13:17 +02:00
|
|
|
if (TM.Options.TrapUnreachable)
|
|
|
|
return fastEmit_(MVT::Other, MVT::Other, ISD::TRAP) != 0;
|
|
|
|
else
|
|
|
|
return true;
|
2008-09-05 03:08:41 +02:00
|
|
|
|
2008-09-10 22:11:02 +02:00
|
|
|
case Instruction::Alloca:
|
|
|
|
// FunctionLowering has the static-sized case covered.
|
2010-07-07 18:29:44 +02:00
|
|
|
if (FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(I)))
|
2008-09-10 22:11:02 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// Dynamic-sized alloca is not handled yet.
|
|
|
|
return false;
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2008-09-25 19:05:24 +02:00
|
|
|
case Instruction::Call:
|
2019-06-06 21:13:36 +02:00
|
|
|
// On AIX, call lowering uses the DAG-ISEL path currently so that the
|
|
|
|
// callee of the direct function call instruction will be mapped to the
|
|
|
|
// symbol for the function's entry point, which is distinct from the
|
|
|
|
// function descriptor symbol. The latter is the symbol whose XCOFF symbol
|
|
|
|
// name is the C-linkage name of the source level function.
|
|
|
|
if (TM.getTargetTriple().isOSAIX())
|
|
|
|
return false;
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCall(I);
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::BitCast:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectBitCast(I);
|
2008-09-04 01:12:08 +02:00
|
|
|
|
|
|
|
case Instruction::FPToSI:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::FP_TO_SINT);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::ZExt:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::ZERO_EXTEND);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::SExt:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::SIGN_EXTEND);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::Trunc:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::TRUNCATE);
|
2008-09-04 01:12:08 +02:00
|
|
|
case Instruction::SIToFP:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::SINT_TO_FP);
|
2008-09-04 01:12:08 +02:00
|
|
|
|
|
|
|
case Instruction::IntToPtr: // Deliberate fall-through.
|
|
|
|
case Instruction::PtrToInt: {
|
2015-07-09 04:09:04 +02:00
|
|
|
EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType());
|
|
|
|
EVT DstVT = TLI.getValueType(DL, I->getType());
|
2008-09-04 01:12:08 +02:00
|
|
|
if (DstVT.bitsGT(SrcVT))
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::ZERO_EXTEND);
|
2008-09-04 01:12:08 +02:00
|
|
|
if (DstVT.bitsLT(SrcVT))
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectCast(I, ISD::TRUNCATE);
|
2020-05-28 23:54:49 +02:00
|
|
|
Register Reg = getRegForValue(I->getOperand(0));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!Reg)
|
|
|
|
return false;
|
2014-09-03 22:56:52 +02:00
|
|
|
updateValueMap(I, Reg);
|
2008-09-04 01:12:08 +02:00
|
|
|
return true;
|
|
|
|
}
|
2008-09-23 23:53:34 +02:00
|
|
|
|
2011-05-16 22:27:46 +02:00
|
|
|
case Instruction::ExtractValue:
|
2014-09-03 20:46:45 +02:00
|
|
|
return selectExtractValue(I);
|
2011-05-16 22:27:46 +02:00
|
|
|
|
[SelDag] Add FREEZE
Summary:
- Add FREEZE node to SelDag
- Lower FreezeInst (in IR) to FREEZE node
- Add Legalization for FREEZE node
Reviewers: qcolombet, bogner, efriedma, lebedev.ri, nlopes, craig.topper, arsenm
Reviewed By: lebedev.ri
Subscribers: wdng, xbolva00, Petar.Avramovic, liuz, lkail, dylanmckay, hiraditya, Jim, arsenm, craig.topper, RKSimon, spatel, lebedev.ri, regehr, trentxintong, nlopes, mkuper, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D29014
2020-03-23 05:03:13 +01:00
|
|
|
case Instruction::Freeze:
|
|
|
|
return selectFreeze(I);
|
|
|
|
|
2010-04-20 17:00:41 +02:00
|
|
|
case Instruction::PHI:
|
|
|
|
llvm_unreachable("FastISel shouldn't visit PHI nodes!");
|
|
|
|
|
2008-09-04 01:12:08 +02:00
|
|
|
default:
|
|
|
|
// Unhandled instruction. Halt "fast" selection and bail.
|
|
|
|
return false;
|
|
|
|
}
|
2008-08-13 22:19:35 +02:00
|
|
|
}
|
|
|
|
|
2014-09-02 23:07:44 +02:00
|
|
|
FastISel::FastISel(FunctionLoweringInfo &FuncInfo,
|
|
|
|
const TargetLibraryInfo *LibInfo,
|
|
|
|
bool SkipTargetIndependentISel)
|
|
|
|
: FuncInfo(FuncInfo), MF(FuncInfo.MF), MRI(FuncInfo.MF->getRegInfo()),
|
2016-07-28 20:40:00 +02:00
|
|
|
MFI(FuncInfo.MF->getFrameInfo()), MCP(*FuncInfo.MF->getConstantPool()),
|
2015-07-07 20:39:02 +02:00
|
|
|
TM(FuncInfo.MF->getTarget()), DL(MF->getDataLayout()),
|
2014-10-09 01:38:33 +02:00
|
|
|
TII(*MF->getSubtarget().getInstrInfo()),
|
|
|
|
TLI(*MF->getSubtarget().getTargetLowering()),
|
|
|
|
TRI(*MF->getSubtarget().getRegisterInfo()), LibInfo(LibInfo),
|
2019-11-02 18:40:52 +01:00
|
|
|
SkipTargetIndependentISel(SkipTargetIndependentISel),
|
|
|
|
LastLocalValue(nullptr), EmitStartPt(nullptr) {}
|
2008-08-20 23:05:57 +02:00
|
|
|
|
2017-02-27 23:45:06 +01:00
|
|
|
FastISel::~FastISel() = default;
|
2008-08-14 23:51:29 +02:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
bool FastISel::fastLowerArguments() { return false; }
|
2013-02-11 02:27:15 +01:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
bool FastISel::fastLowerCall(CallLoweringInfo & /*CLI*/) { return false; }
|
2014-07-12 00:01:42 +02:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
bool FastISel::fastLowerIntrinsicCall(const IntrinsicInst * /*II*/) {
|
2014-07-11 22:42:12 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
unsigned FastISel::fastEmit_(MVT, MVT, unsigned) { return 0; }
|
2008-08-13 22:19:35 +02:00
|
|
|
|
2021-03-09 21:04:03 +01:00
|
|
|
unsigned FastISel::fastEmit_r(MVT, MVT, unsigned, unsigned /*Op0*/) {
|
2008-08-13 22:19:35 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
unsigned FastISel::fastEmit_rr(MVT, MVT, unsigned, unsigned /*Op0*/,
|
2021-03-09 21:04:03 +01:00
|
|
|
unsigned /*Op1*/) {
|
2008-08-13 22:19:35 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
unsigned FastISel::fastEmit_i(MVT, MVT, unsigned, uint64_t /*Imm*/) {
|
2008-08-21 00:45:34 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
unsigned FastISel::fastEmit_f(MVT, MVT, unsigned,
|
2014-09-03 20:46:45 +02:00
|
|
|
const ConstantFP * /*FPImm*/) {
|
2008-08-27 03:09:54 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
unsigned FastISel::fastEmit_ri(MVT, MVT, unsigned, unsigned /*Op0*/,
|
2021-03-09 21:04:03 +01:00
|
|
|
uint64_t /*Imm*/) {
|
2008-08-21 03:41:07 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-09-03 22:56:59 +02:00
|
|
|
/// This method is a wrapper of fastEmit_ri. It first tries to emit an
|
|
|
|
/// instruction with an immediate operand using fastEmit_ri.
|
2008-08-21 00:45:34 +02:00
|
|
|
/// If that fails, it materializes the immediate into a register and try
|
2014-09-03 22:56:59 +02:00
|
|
|
/// fastEmit_rr instead.
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
uint64_t Imm, MVT ImmType) {
|
2011-04-17 22:23:29 +02:00
|
|
|
// If this is a multiply by a power of two, emit this as a shift left.
|
|
|
|
if (Opcode == ISD::MUL && isPowerOf2_64(Imm)) {
|
|
|
|
Opcode = ISD::SHL;
|
|
|
|
Imm = Log2_64(Imm);
|
2011-04-18 08:55:51 +02:00
|
|
|
} else if (Opcode == ISD::UDIV && isPowerOf2_64(Imm)) {
|
|
|
|
// div x, 8 -> srl x, 3
|
|
|
|
Opcode = ISD::SRL;
|
|
|
|
Imm = Log2_64(Imm);
|
2011-04-17 22:23:29 +02:00
|
|
|
}
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2011-04-17 22:23:29 +02:00
|
|
|
// Horrible hack (to be removed), check to make sure shift amounts are
|
|
|
|
// in-range.
|
|
|
|
if ((Opcode == ISD::SHL || Opcode == ISD::SRA || Opcode == ISD::SRL) &&
|
|
|
|
Imm >= VT.getSizeInBits())
|
|
|
|
return 0;
|
2011-04-23 01:38:06 +02:00
|
|
|
|
2008-08-21 00:45:34 +02:00
|
|
|
// First check if immediate type is legal. If not, we can't use the ri form.
|
2021-03-09 21:04:03 +01:00
|
|
|
Register ResultReg = fastEmit_ri(VT, VT, Opcode, Op0, Imm);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (ResultReg)
|
2008-08-21 00:45:34 +02:00
|
|
|
return ResultReg;
|
2020-04-08 16:57:11 +02:00
|
|
|
Register MaterialReg = fastEmit_i(ImmType, ImmType, ISD::Constant, Imm);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!MaterialReg) {
|
2011-04-30 01:34:52 +02:00
|
|
|
// This is a bit ugly/slow, but failing here means falling out of
|
|
|
|
// fast-isel, which would be very slow.
|
2014-09-03 20:46:45 +02:00
|
|
|
IntegerType *ITy =
|
|
|
|
IntegerType::get(FuncInfo.Fn->getContext(), VT.getSizeInBits());
|
2011-04-30 01:34:52 +02:00
|
|
|
MaterialReg = getRegForValue(ConstantInt::get(ITy, Imm));
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!MaterialReg)
|
|
|
|
return 0;
|
2011-04-30 01:34:52 +02:00
|
|
|
}
|
2021-03-09 21:04:03 +01:00
|
|
|
return fastEmit_rr(VT, VT, Opcode, Op0, MaterialReg);
|
2008-08-21 03:41:07 +02:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::createResultReg(const TargetRegisterClass *RC) {
|
2008-08-21 03:41:07 +02:00
|
|
|
return MRI.createVirtualRegister(RC);
|
2008-08-21 00:45:34 +02:00
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::constrainOperandRegClass(const MCInstrDesc &II, Register Op,
|
2014-09-03 20:46:45 +02:00
|
|
|
unsigned OpNum) {
|
2020-04-08 16:57:11 +02:00
|
|
|
if (Op.isVirtual()) {
|
2014-04-15 15:59:49 +02:00
|
|
|
const TargetRegisterClass *RegClass =
|
|
|
|
TII.getRegClass(II, OpNum, &TRI, *FuncInfo.MF);
|
|
|
|
if (!MRI.constrainRegClass(Op, RegClass)) {
|
|
|
|
// If it's not legal to COPY between the register classes, something
|
|
|
|
// has gone very wrong before we got here.
|
2020-05-28 23:54:49 +02:00
|
|
|
Register NewOp = createResultReg(RegClass);
|
2014-04-15 15:59:49 +02:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), NewOp).addReg(Op);
|
|
|
|
return NewOp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2008-08-13 22:19:35 +02:00
|
|
|
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg);
|
2008-08-13 22:19:35 +02:00
|
|
|
return ResultReg;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_r(unsigned MachineInstOpcode,
|
2021-03-09 21:04:03 +01:00
|
|
|
const TargetRegisterClass *RC, unsigned Op0) {
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2008-08-13 22:19:35 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2014-04-15 15:59:49 +02:00
|
|
|
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
|
|
|
|
|
2008-09-08 10:38:20 +02:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0);
|
2008-09-08 10:38:20 +02:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2008-09-08 10:38:20 +02:00
|
|
|
}
|
|
|
|
|
2008-08-13 22:19:35 +02:00
|
|
|
return ResultReg;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
unsigned Op1) {
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2008-08-13 22:19:35 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2014-04-15 15:59:49 +02:00
|
|
|
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
|
|
|
|
Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
|
|
|
|
|
2008-09-08 10:38:20 +02:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
|
|
|
.addReg(Op1);
|
2008-09-08 10:38:20 +02:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
|
|
|
.addReg(Op1);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2008-09-08 10:38:20 +02:00
|
|
|
}
|
2008-08-13 22:19:35 +02:00
|
|
|
return ResultReg;
|
|
|
|
}
|
2008-08-21 03:41:07 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_rrr(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
unsigned Op1, unsigned Op2) {
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2011-05-05 19:59:04 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2014-04-15 15:59:49 +02:00
|
|
|
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
|
|
|
|
Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
|
|
|
|
Op2 = constrainOperandRegClass(II, Op2, II.getNumDefs() + 2);
|
|
|
|
|
2011-05-05 19:59:04 +02:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
|
|
|
.addReg(Op1)
|
|
|
|
.addReg(Op2);
|
2011-05-05 19:59:04 +02:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
|
|
|
.addReg(Op1)
|
|
|
|
.addReg(Op2);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2011-05-05 19:59:04 +02:00
|
|
|
}
|
|
|
|
return ResultReg;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_ri(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
uint64_t Imm) {
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2008-08-21 03:41:07 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2014-08-27 22:47:33 +02:00
|
|
|
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
|
2014-04-15 15:59:49 +02:00
|
|
|
|
2008-09-08 10:38:20 +02:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(Imm);
|
2008-09-08 10:38:20 +02:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(Imm);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2008-09-08 10:38:20 +02:00
|
|
|
}
|
2008-08-21 03:41:07 +02:00
|
|
|
return ResultReg;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_rii(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
uint64_t Imm1, uint64_t Imm2) {
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2011-03-11 22:33:55 +01:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2014-04-15 15:59:49 +02:00
|
|
|
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
|
|
|
|
|
2011-03-11 22:33:55 +01:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(Imm1)
|
|
|
|
.addImm(Imm2);
|
2011-03-11 22:33:55 +01:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(Imm1)
|
|
|
|
.addImm(Imm2);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2011-03-11 22:33:55 +01:00
|
|
|
}
|
|
|
|
return ResultReg;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_f(unsigned MachineInstOpcode,
|
2015-08-24 20:44:37 +02:00
|
|
|
const TargetRegisterClass *RC,
|
|
|
|
const ConstantFP *FPImm) {
|
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2015-08-24 20:44:37 +02:00
|
|
|
|
|
|
|
if (II.getNumDefs() >= 1)
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
|
|
|
.addFPImm(FPImm);
|
|
|
|
else {
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
|
|
|
.addFPImm(FPImm);
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
|
|
|
}
|
|
|
|
return ResultReg;
|
|
|
|
}
|
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_rri(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
unsigned Op1, uint64_t Imm) {
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2008-08-21 03:41:07 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2014-04-15 15:59:49 +02:00
|
|
|
Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());
|
|
|
|
Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);
|
|
|
|
|
2008-09-08 10:38:20 +02:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
|
|
|
.addReg(Op1)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(Imm);
|
2008-09-08 10:38:20 +02:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)
|
2021-03-09 21:04:03 +01:00
|
|
|
.addReg(Op0)
|
|
|
|
.addReg(Op1)
|
2014-09-03 20:46:45 +02:00
|
|
|
.addImm(Imm);
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2008-09-08 10:38:20 +02:00
|
|
|
}
|
2008-08-21 03:41:07 +02:00
|
|
|
return ResultReg;
|
|
|
|
}
|
2008-08-25 22:20:32 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_i(unsigned MachineInstOpcode,
|
2014-09-03 20:46:45 +02:00
|
|
|
const TargetRegisterClass *RC, uint64_t Imm) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(RC);
|
2011-06-28 21:10:37 +02:00
|
|
|
const MCInstrDesc &II = TII.get(MachineInstOpcode);
|
2010-11-23 04:31:01 +01:00
|
|
|
|
2008-09-08 10:38:20 +02:00
|
|
|
if (II.getNumDefs() >= 1)
|
2014-09-03 20:46:45 +02:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, ResultReg)
|
|
|
|
.addImm(Imm);
|
2008-09-08 10:38:20 +02:00
|
|
|
else {
|
2014-02-18 23:05:46 +01:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II).addImm(Imm);
|
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
|
|
|
TII.get(TargetOpcode::COPY), ResultReg).addReg(II.ImplicitDefs[0]);
|
2008-09-08 10:38:20 +02:00
|
|
|
}
|
2008-08-25 22:20:32 +02:00
|
|
|
return ResultReg;
|
2008-08-26 00:20:39 +02:00
|
|
|
}
|
2008-08-28 00:30:02 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register FastISel::fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0,
|
2021-03-09 21:04:03 +01:00
|
|
|
uint32_t Idx) {
|
2020-04-08 16:57:11 +02:00
|
|
|
Register ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
|
2019-08-02 01:27:28 +02:00
|
|
|
assert(Register::isVirtualRegister(Op0) &&
|
2010-07-08 18:40:22 +02:00
|
|
|
"Cannot yet extract from physregs");
|
2012-05-20 08:38:37 +02:00
|
|
|
const TargetRegisterClass *RC = MRI.getRegClass(Op0);
|
|
|
|
MRI.constrainRegClass(Op0, TRI.getSubClassWithSubReg(RC, Idx));
|
2014-09-03 20:46:45 +02:00
|
|
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::COPY),
|
2021-03-09 21:04:03 +01:00
|
|
|
ResultReg).addReg(Op0, 0, Idx);
|
2008-08-28 00:30:02 +02:00
|
|
|
return ResultReg;
|
|
|
|
}
|
2009-03-13 21:42:20 +01:00
|
|
|
|
2014-09-03 22:56:52 +02:00
|
|
|
/// Emit MachineInstrs to compute the value of Op with all but the least
|
|
|
|
/// significant bit set to zero.
|
2021-03-09 21:04:03 +01:00
|
|
|
Register FastISel::fastEmitZExtFromI1(MVT VT, unsigned Op0) {
|
|
|
|
return fastEmit_ri(VT, VT, ISD::AND, Op0, 1);
|
2009-03-13 21:42:20 +01:00
|
|
|
}
|
2010-04-22 22:46:50 +02:00
|
|
|
|
|
|
|
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
|
|
|
|
/// Emit code to ensure constants are copied into registers when needed.
|
|
|
|
/// Remember the virtual registers that need to be added to the Machine PHI
|
|
|
|
/// nodes as input. We cannot just directly add them, because expansion
|
|
|
|
/// might result in multiple MBB's for one BB. As such, the start of the
|
|
|
|
/// BB might correspond to a different MBB than the end.
|
2014-09-03 20:46:45 +02:00
|
|
|
bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
|
2018-10-15 12:04:59 +02:00
|
|
|
const Instruction *TI = LLVMBB->getTerminator();
|
2010-04-22 22:46:50 +02:00
|
|
|
|
|
|
|
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
|
2014-08-28 04:06:55 +02:00
|
|
|
FuncInfo.OrigNumPHINodesToUpdate = FuncInfo.PHINodesToUpdate.size();
|
2010-04-22 22:46:50 +02:00
|
|
|
|
|
|
|
// Check successor nodes' PHI nodes that expect a constant to be available
|
|
|
|
// from this block.
|
|
|
|
for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
|
|
|
|
const BasicBlock *SuccBB = TI->getSuccessor(succ);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!isa<PHINode>(SuccBB->begin()))
|
|
|
|
continue;
|
2010-07-07 18:29:44 +02:00
|
|
|
MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB];
|
2010-04-22 22:46:50 +02:00
|
|
|
|
|
|
|
// If this terminator has multiple identical successors (common for
|
|
|
|
// switches), only handle each succ once.
|
2014-11-19 08:49:26 +01:00
|
|
|
if (!SuccsHandled.insert(SuccMBB).second)
|
2014-09-03 20:46:45 +02:00
|
|
|
continue;
|
2010-04-22 22:46:50 +02:00
|
|
|
|
|
|
|
MachineBasicBlock::iterator MBBI = SuccMBB->begin();
|
|
|
|
|
|
|
|
// At this point we know that there is a 1-1 correspondence between LLVM PHI
|
|
|
|
// nodes and Machine PHI nodes, but the incoming operands have not been
|
|
|
|
// emitted yet.
|
2017-12-30 16:27:33 +01:00
|
|
|
for (const PHINode &PN : SuccBB->phis()) {
|
2010-04-22 22:46:50 +02:00
|
|
|
// Ignore dead phi's.
|
2017-12-30 16:27:33 +01:00
|
|
|
if (PN.use_empty())
|
2014-09-03 20:46:45 +02:00
|
|
|
continue;
|
2010-04-22 22:46:50 +02:00
|
|
|
|
|
|
|
// Only handle legal types. Two interesting things to note here. First,
|
|
|
|
// by bailing out early, we may leave behind some dead instructions,
|
|
|
|
// since SelectionDAG's HandlePHINodesInSuccessorBlocks will insert its
|
2011-04-15 07:18:47 +02:00
|
|
|
// own moves. Second, this check is necessary because FastISel doesn't
|
2010-07-02 02:10:16 +02:00
|
|
|
// use CreateRegs to create registers, so it always creates
|
2010-04-22 22:46:50 +02:00
|
|
|
// exactly one register for each non-void instruction.
|
2017-12-30 16:27:33 +01:00
|
|
|
EVT VT = TLI.getValueType(DL, PN.getType(), /*AllowUnknown=*/true);
|
2010-04-22 22:46:50 +02:00
|
|
|
if (VT == MVT::Other || !TLI.isTypeLegal(VT)) {
|
2012-02-04 01:39:19 +01:00
|
|
|
// Handle integer promotions, though, because they're common and easy.
|
2014-10-09 00:25:45 +02:00
|
|
|
if (!(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)) {
|
2014-08-28 04:06:55 +02:00
|
|
|
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
|
2010-04-22 22:46:50 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-30 16:27:33 +01:00
|
|
|
const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB);
|
2010-04-22 22:46:50 +02:00
|
|
|
|
[FastISel] Flush local value map on every instruction
Local values are constants or addresses that can't be folded into
the instruction that uses them. FastISel materializes these in a
"local value" area that always dominates the current insertion
point, to try to avoid materializing these values more than once
(per block).
https://reviews.llvm.org/D43093 added code to sink these local
value instructions to their first use, which has two beneficial
effects. One, it is likely to avoid some unnecessary spills and
reloads; two, it allows us to attach the debug location of the
user to the local value instruction. The latter effect can
improve the debugging experience for debuggers with a "set next
statement" feature, such as the Visual Studio debugger and PS4
debugger, because instructions to set up constants for a given
statement will be associated with the appropriate source line.
There are also some constants (primarily addresses) that could be
produced by no-op casts or GEP instructions; the main difference
from "local value" instructions is that these are values from
separate IR instructions, and therefore could have multiple users
across multiple basic blocks. D43093 avoided sinking these, even
though they were emitted to the same "local value" area as the
other instructions. The patch comment for D43093 states:
Local values may also be used by no-op casts, which adds the
register to the RegFixups table. Without reversing the RegFixups
map direction, we don't have enough information to sink these
instructions.
This patch undoes most of D43093, and instead flushes the local
value map after(*) every IR instruction, using that instruction's
debug location. This avoids sometimes incorrect locations used
previously, and emits instructions in a more natural order.
In addition, constants materialized due to PHI instructions are
not assigned a debug location immediately; instead, when the
local value map is flushed, if the first local value instruction
has no debug location, it is given the same location as the
first non-local-value-map instruction. This prevents PHIs
from introducing unattributed instructions, which would either
be implicitly attributed to the location for the preceding IR
instruction, or given line 0 if they are at the beginning of
a machine basic block. Neither of those consequences is good
for debugging.
This does mean materialized values are not re-used across IR
instruction boundaries; however, only about 5% of those values
were reused in an experimental self-build of clang.
(*) Actually, just prior to the next instruction. It seems like
it would be cleaner the other way, but I was having trouble
getting that to work.
This reapplies commits cf1c774d and dc35368c, and adds the
modification to PHI handling, which should avoid problems
with debugging under gdb.
Differential Revision: https://reviews.llvm.org/D91734
2021-01-11 17:32:36 +01:00
|
|
|
// Set the DebugLoc for the copy. Use the location of the operand if
|
|
|
|
// there is one; otherwise no location, flushLocalValueMap will fix it.
|
|
|
|
DbgLoc = DebugLoc();
|
2014-09-03 20:46:45 +02:00
|
|
|
if (const auto *Inst = dyn_cast<Instruction>(PHIOp))
|
2014-02-18 23:05:46 +01:00
|
|
|
DbgLoc = Inst->getDebugLoc();
|
2010-05-07 03:10:20 +02:00
|
|
|
|
2020-04-08 16:57:11 +02:00
|
|
|
Register Reg = getRegForValue(PHIOp);
|
2014-08-28 04:06:55 +02:00
|
|
|
if (!Reg) {
|
|
|
|
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
|
2010-04-22 22:46:50 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-07-08 20:36:41 +02:00
|
|
|
FuncInfo.PHINodesToUpdate.push_back(std::make_pair(&*MBBI++, Reg));
|
2014-02-18 23:05:46 +01:00
|
|
|
DbgLoc = DebugLoc();
|
2010-04-22 22:46:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-04-20 00:29:18 +02:00
|
|
|
|
|
|
|
bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) {
|
2013-04-20 01:26:18 +02:00
|
|
|
assert(LI->hasOneUse() &&
|
2014-09-03 20:46:45 +02:00
|
|
|
"tryToFoldLoad expected a LoadInst with a single use");
|
2013-04-20 00:29:18 +02:00
|
|
|
// We know that the load has a single use, but don't know what it is. If it
|
|
|
|
// isn't one of the folded instructions, then we can't succeed here. Handle
|
|
|
|
// this by scanning the single-use users of the load until we get to FoldInst.
|
2014-09-03 20:46:45 +02:00
|
|
|
unsigned MaxUsers = 6; // Don't scan down huge single-use chains of instrs.
|
2013-04-20 00:29:18 +02:00
|
|
|
|
2014-03-09 04:16:01 +01:00
|
|
|
const Instruction *TheUser = LI->user_back();
|
2014-09-03 20:46:45 +02:00
|
|
|
while (TheUser != FoldInst && // Scan up until we find FoldInst.
|
2013-04-20 00:29:18 +02:00
|
|
|
// Stay in the right block.
|
|
|
|
TheUser->getParent() == FoldInst->getParent() &&
|
2014-09-03 20:46:45 +02:00
|
|
|
--MaxUsers) { // Don't scan too far.
|
2013-04-20 00:29:18 +02:00
|
|
|
// If there are multiple or no uses of this instruction, then bail out.
|
|
|
|
if (!TheUser->hasOneUse())
|
|
|
|
return false;
|
|
|
|
|
2014-03-09 04:16:01 +01:00
|
|
|
TheUser = TheUser->user_back();
|
2013-04-20 00:29:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we didn't find the fold instruction, then we failed to collapse the
|
|
|
|
// sequence.
|
|
|
|
if (TheUser != FoldInst)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Don't try to fold volatile loads. Target has to deal with alignment
|
|
|
|
// constraints.
|
2013-04-20 01:26:18 +02:00
|
|
|
if (LI->isVolatile())
|
|
|
|
return false;
|
2013-04-20 00:29:18 +02:00
|
|
|
|
|
|
|
// Figure out which vreg this is going into. If there is no assigned vreg yet
|
|
|
|
// then there actually was no reference to it. Perhaps the load is referenced
|
|
|
|
// by a dead instruction.
|
2020-04-08 16:57:11 +02:00
|
|
|
Register LoadReg = getRegForValue(LI);
|
2014-09-03 20:46:45 +02:00
|
|
|
if (!LoadReg)
|
2013-04-20 00:29:18 +02:00
|
|
|
return false;
|
|
|
|
|
2013-04-20 01:26:18 +02:00
|
|
|
// We can't fold if this vreg has no uses or more than one use. Multiple uses
|
|
|
|
// may mean that the instruction got lowered to multiple MIs, or the use of
|
|
|
|
// the loaded value ended up being multiple operands of the result.
|
|
|
|
if (!MRI.hasOneUse(LoadReg))
|
2013-04-20 00:29:18 +02:00
|
|
|
return false;
|
|
|
|
|
2013-04-20 01:26:18 +02:00
|
|
|
MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LoadReg);
|
2014-03-14 00:12:04 +01:00
|
|
|
MachineInstr *User = RI->getParent();
|
2013-04-20 00:29:18 +02:00
|
|
|
|
|
|
|
// Set the insertion point properly. Folding the load can cause generation of
|
2013-04-20 01:26:18 +02:00
|
|
|
// other random instructions (like sign extends) for addressing modes; make
|
2013-04-20 00:29:18 +02:00
|
|
|
// sure they get inserted in a logical place before the new instruction.
|
|
|
|
FuncInfo.InsertPt = User;
|
|
|
|
FuncInfo.MBB = User->getParent();
|
|
|
|
|
|
|
|
// Ask the target to try folding the load.
|
|
|
|
return tryToFoldLoadIntoMI(User, RI.getOperandNo(), LI);
|
|
|
|
}
|
|
|
|
|
2013-11-15 20:09:27 +01:00
|
|
|
bool FastISel::canFoldAddIntoGEP(const User *GEP, const Value *Add) {
|
|
|
|
// Must be an add.
|
|
|
|
if (!isa<AddOperator>(Add))
|
|
|
|
return false;
|
|
|
|
// Type size needs to match.
|
2014-02-18 23:05:46 +01:00
|
|
|
if (DL.getTypeSizeInBits(GEP->getType()) !=
|
|
|
|
DL.getTypeSizeInBits(Add->getType()))
|
2013-11-15 20:09:27 +01:00
|
|
|
return false;
|
|
|
|
// Must be in the same basic block.
|
|
|
|
if (isa<Instruction>(Add) &&
|
|
|
|
FuncInfo.MBBMap[cast<Instruction>(Add)->getParent()] != FuncInfo.MBB)
|
|
|
|
return false;
|
|
|
|
// Must have a constant operand.
|
|
|
|
return isa<ConstantInt>(cast<AddOperator>(Add)->getOperand(1));
|
|
|
|
}
|
2013-04-20 00:29:18 +02:00
|
|
|
|
2014-06-13 01:27:57 +02:00
|
|
|
MachineMemOperand *
|
|
|
|
FastISel::createMachineMemOperandFor(const Instruction *I) const {
|
|
|
|
const Value *Ptr;
|
|
|
|
Type *ValTy;
|
2020-03-31 11:43:50 +02:00
|
|
|
MaybeAlign Alignment;
|
2016-07-15 20:26:59 +02:00
|
|
|
MachineMemOperand::Flags Flags;
|
2014-06-13 01:27:57 +02:00
|
|
|
bool IsVolatile;
|
|
|
|
|
|
|
|
if (const auto *LI = dyn_cast<LoadInst>(I)) {
|
2020-03-31 11:43:50 +02:00
|
|
|
Alignment = LI->getAlign();
|
2014-06-13 01:27:57 +02:00
|
|
|
IsVolatile = LI->isVolatile();
|
|
|
|
Flags = MachineMemOperand::MOLoad;
|
|
|
|
Ptr = LI->getPointerOperand();
|
|
|
|
ValTy = LI->getType();
|
|
|
|
} else if (const auto *SI = dyn_cast<StoreInst>(I)) {
|
2020-03-31 11:43:50 +02:00
|
|
|
Alignment = SI->getAlign();
|
2014-06-13 01:27:57 +02:00
|
|
|
IsVolatile = SI->isVolatile();
|
|
|
|
Flags = MachineMemOperand::MOStore;
|
|
|
|
Ptr = SI->getPointerOperand();
|
|
|
|
ValTy = SI->getValueOperand()->getType();
|
2014-09-03 20:46:45 +02:00
|
|
|
} else
|
2014-06-13 01:27:57 +02:00
|
|
|
return nullptr;
|
|
|
|
|
2019-09-04 19:46:55 +02:00
|
|
|
bool IsNonTemporal = I->hasMetadata(LLVMContext::MD_nontemporal);
|
|
|
|
bool IsInvariant = I->hasMetadata(LLVMContext::MD_invariant_load);
|
|
|
|
bool IsDereferenceable = I->hasMetadata(LLVMContext::MD_dereferenceable);
|
2014-11-11 22:30:22 +01:00
|
|
|
const MDNode *Ranges = I->getMetadata(LLVMContext::MD_range);
|
2014-06-13 01:27:57 +02:00
|
|
|
|
2014-07-24 14:16:19 +02:00
|
|
|
AAMDNodes AAInfo;
|
|
|
|
I->getAAMetadata(AAInfo);
|
|
|
|
|
2020-03-31 11:43:50 +02:00
|
|
|
if (!Alignment) // Ensure that codegen never sees alignment 0.
|
|
|
|
Alignment = DL.getABITypeAlign(ValTy);
|
2014-06-13 01:27:57 +02:00
|
|
|
|
2014-10-09 01:38:33 +02:00
|
|
|
unsigned Size = DL.getTypeStoreSize(ValTy);
|
2014-06-13 01:27:57 +02:00
|
|
|
|
|
|
|
if (IsVolatile)
|
|
|
|
Flags |= MachineMemOperand::MOVolatile;
|
|
|
|
if (IsNonTemporal)
|
|
|
|
Flags |= MachineMemOperand::MONonTemporal;
|
[CodeGen] Split out the notions of MI invariance and MI dereferenceability.
Summary:
An IR load can be invariant, dereferenceable, neither, or both. But
currently, MI's notion of invariance is IR-invariant &&
IR-dereferenceable.
This patch splits up the notions of invariance and dereferenceability at
the MI level. It's NFC, so adds some probably-unnecessary
"is-dereferenceable" checks, which we can remove later if desired.
Reviewers: chandlerc, tstellarAMD
Subscribers: jholewinski, arsenm, nemanjai, llvm-commits
Differential Revision: https://reviews.llvm.org/D23371
llvm-svn: 281151
2016-09-11 03:38:58 +02:00
|
|
|
if (IsDereferenceable)
|
|
|
|
Flags |= MachineMemOperand::MODereferenceable;
|
2014-06-13 01:27:57 +02:00
|
|
|
if (IsInvariant)
|
|
|
|
Flags |= MachineMemOperand::MOInvariant;
|
|
|
|
|
|
|
|
return FuncInfo.MF->getMachineMemOperand(MachinePointerInfo(Ptr), Flags, Size,
|
2020-03-31 11:43:50 +02:00
|
|
|
*Alignment, AAInfo, Ranges);
|
2014-06-13 01:27:57 +02:00
|
|
|
}
|
2014-09-15 22:47:13 +02:00
|
|
|
|
|
|
|
CmpInst::Predicate FastISel::optimizeCmpPredicate(const CmpInst *CI) const {
|
|
|
|
// If both operands are the same, then try to optimize or fold the cmp.
|
|
|
|
CmpInst::Predicate Predicate = CI->getPredicate();
|
|
|
|
if (CI->getOperand(0) != CI->getOperand(1))
|
|
|
|
return Predicate;
|
|
|
|
|
|
|
|
switch (Predicate) {
|
|
|
|
default: llvm_unreachable("Invalid predicate!");
|
|
|
|
case CmpInst::FCMP_FALSE: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::FCMP_OEQ: Predicate = CmpInst::FCMP_ORD; break;
|
|
|
|
case CmpInst::FCMP_OGT: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::FCMP_OGE: Predicate = CmpInst::FCMP_ORD; break;
|
|
|
|
case CmpInst::FCMP_OLT: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::FCMP_OLE: Predicate = CmpInst::FCMP_ORD; break;
|
|
|
|
case CmpInst::FCMP_ONE: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::FCMP_ORD: Predicate = CmpInst::FCMP_ORD; break;
|
|
|
|
case CmpInst::FCMP_UNO: Predicate = CmpInst::FCMP_UNO; break;
|
|
|
|
case CmpInst::FCMP_UEQ: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::FCMP_UGT: Predicate = CmpInst::FCMP_UNO; break;
|
|
|
|
case CmpInst::FCMP_UGE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::FCMP_ULT: Predicate = CmpInst::FCMP_UNO; break;
|
|
|
|
case CmpInst::FCMP_ULE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::FCMP_UNE: Predicate = CmpInst::FCMP_UNO; break;
|
|
|
|
case CmpInst::FCMP_TRUE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
|
|
|
|
case CmpInst::ICMP_EQ: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::ICMP_NE: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::ICMP_UGT: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::ICMP_UGE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::ICMP_ULT: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::ICMP_ULE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::ICMP_SGT: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::ICMP_SGE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
case CmpInst::ICMP_SLT: Predicate = CmpInst::FCMP_FALSE; break;
|
|
|
|
case CmpInst::ICMP_SLE: Predicate = CmpInst::FCMP_TRUE; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Predicate;
|
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
Note: I accidentally committed a bogus older version of this patch previously.
llvm-svn: 218787
2014-10-01 20:55:02 +02:00
|
|
|
}
|