2016-02-12 01:44:59 +08:00
|
|
|
//===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- C++ -*-==//
|
|
|
|
//
|
2019-01-19 16:50:56 +08: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
|
2016-02-12 01:44:59 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// \file
|
|
|
|
/// This file implements the MachineIRBuidler class.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
2020-07-27 09:25:10 +08:00
|
|
|
#include "llvm/Analysis/MemoryLocation.h"
|
2018-12-06 04:14:52 +08:00
|
|
|
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
|
2016-02-12 01:44:59 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2016-09-09 19:46:34 +08:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2017-11-08 09:01:31 +08:00
|
|
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
2019-01-30 10:57:43 +08:00
|
|
|
#include "llvm/CodeGen/TargetLowering.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/TargetOpcodes.h"
|
|
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
2017-01-27 07:39:14 +08:00
|
|
|
#include "llvm/IR/DebugInfo.h"
|
2016-02-12 01:44:59 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
void MachineIRBuilder::setMF(MachineFunction &MF) {
|
2018-04-10 01:30:56 +08:00
|
|
|
State.MF = &MF;
|
|
|
|
State.MBB = nullptr;
|
|
|
|
State.MRI = &MF.getRegInfo();
|
|
|
|
State.TII = MF.getSubtarget().getInstrInfo();
|
|
|
|
State.DL = DebugLoc();
|
|
|
|
State.II = MachineBasicBlock::iterator();
|
2018-12-06 04:14:52 +08:00
|
|
|
State.Observer = nullptr;
|
2018-04-10 01:30:56 +08:00
|
|
|
}
|
|
|
|
|
2016-03-12 01:27:58 +08:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Build instruction variants.
|
|
|
|
//------------------------------------------------------------------------------
|
2016-07-27 00:45:26 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
|
2018-04-10 01:30:56 +08:00
|
|
|
MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode));
|
2016-09-22 21:49:25 +08:00
|
|
|
return MIB;
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
|
2016-07-30 01:43:52 +08:00
|
|
|
getMBB().insert(getInsertPt(), MIB);
|
2018-05-10 01:28:18 +08:00
|
|
|
recordInsertion(MIB);
|
2016-07-30 01:43:52 +08:00
|
|
|
return MIB;
|
2016-02-12 02:53:28 +08:00
|
|
|
}
|
|
|
|
|
2017-08-02 06:37:35 +08:00
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildDirectDbgValue(Register Reg, const MDNode *Variable,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
const MDNode *Expr) {
|
2017-01-27 07:39:14 +08:00
|
|
|
assert(isa<DILocalVariable>(Variable) && "not a variable");
|
|
|
|
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(
|
|
|
|
cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
|
|
|
return insertInstr(BuildMI(getMF(), getDL(),
|
|
|
|
getTII().get(TargetOpcode::DBG_VALUE),
|
2017-08-02 06:37:35 +08:00
|
|
|
/*IsIndirect*/ false, Reg, Variable, Expr));
|
2017-01-27 07:39:14 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildIndirectDbgValue(Register Reg, const MDNode *Variable,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
const MDNode *Expr) {
|
2017-01-27 07:39:14 +08:00
|
|
|
assert(isa<DILocalVariable>(Variable) && "not a variable");
|
|
|
|
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(
|
|
|
|
cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
|
|
|
return insertInstr(BuildMI(getMF(), getDL(),
|
|
|
|
getTII().get(TargetOpcode::DBG_VALUE),
|
2020-02-06 01:27:44 +08:00
|
|
|
/*IsIndirect*/ true, Reg, Variable, Expr));
|
2017-01-27 07:39:14 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
|
|
|
|
const MDNode *Variable,
|
|
|
|
const MDNode *Expr) {
|
2017-01-27 07:39:14 +08:00
|
|
|
assert(isa<DILocalVariable>(Variable) && "not a variable");
|
|
|
|
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(
|
|
|
|
cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
2017-01-27 07:39:14 +08:00
|
|
|
return buildInstr(TargetOpcode::DBG_VALUE)
|
|
|
|
.addFrameIndex(FI)
|
2020-02-06 01:27:44 +08:00
|
|
|
.addImm(0)
|
2017-01-27 07:39:14 +08:00
|
|
|
.addMetadata(Variable)
|
2020-02-06 01:27:44 +08:00
|
|
|
.addMetadata(Expr);
|
2017-01-27 07:39:14 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
|
|
|
|
const MDNode *Variable,
|
|
|
|
const MDNode *Expr) {
|
2017-01-27 07:39:14 +08:00
|
|
|
assert(isa<DILocalVariable>(Variable) && "not a variable");
|
|
|
|
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(
|
|
|
|
cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
[GlobalISel] fix crash in IRTranslator, MachineIRBuilder when translating @llvm.dbg.value intrinsic and using -debug
Summary:
Fix crash when using -debug caused by the GlobalISel observer trying to print
an incomplete DBG_VALUE instruction. This was caused by the MachineIRBuilder
using buildInstr, which immediately inserts the instruction causing print,
instead of using BuildMI to first build up the instruction and using
insertInstr when finished.
Add RUN-line to existing debug-insts.ll test with -debug flag set to make sure
no crash is happening.
Also fixed a missing %s in the 2nd RUN-line of the same test.
Reviewers: t.p.northover, aditya_nandakumar, aemerson, dsanders, arsenm
Reviewed By: arsenm
Subscribers: wdng, arsenm, rovka, hiraditya, volkan, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D76934
2020-03-27 23:47:37 +08:00
|
|
|
auto MIB = buildInstrNoInsert(TargetOpcode::DBG_VALUE);
|
2017-01-27 07:39:14 +08:00
|
|
|
if (auto *CI = dyn_cast<ConstantInt>(&C)) {
|
|
|
|
if (CI->getBitWidth() > 64)
|
|
|
|
MIB.addCImm(CI);
|
|
|
|
else
|
|
|
|
MIB.addImm(CI->getZExtValue());
|
2017-03-08 04:34:20 +08:00
|
|
|
} else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
|
2017-03-08 04:52:57 +08:00
|
|
|
MIB.addFPImm(CFP);
|
2017-03-08 04:34:20 +08:00
|
|
|
} else {
|
2020-06-28 22:06:26 +08:00
|
|
|
// Insert $noreg if we didn't find a usable constant and had to drop it.
|
|
|
|
MIB.addReg(Register());
|
2017-03-08 04:34:20 +08:00
|
|
|
}
|
2017-01-27 07:39:14 +08:00
|
|
|
|
[GlobalISel] fix crash in IRTranslator, MachineIRBuilder when translating @llvm.dbg.value intrinsic and using -debug
Summary:
Fix crash when using -debug caused by the GlobalISel observer trying to print
an incomplete DBG_VALUE instruction. This was caused by the MachineIRBuilder
using buildInstr, which immediately inserts the instruction causing print,
instead of using BuildMI to first build up the instruction and using
insertInstr when finished.
Add RUN-line to existing debug-insts.ll test with -debug flag set to make sure
no crash is happening.
Also fixed a missing %s in the 2nd RUN-line of the same test.
Reviewers: t.p.northover, aditya_nandakumar, aemerson, dsanders, arsenm
Reviewed By: arsenm
Subscribers: wdng, arsenm, rovka, hiraditya, volkan, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D76934
2020-03-27 23:47:37 +08:00
|
|
|
MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
|
|
|
|
return insertInstr(MIB);
|
2017-01-27 07:39:14 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildDbgLabel(const MDNode *Label) {
|
2018-08-17 23:22:04 +08:00
|
|
|
assert(isa<DILabel>(Label) && "not a label");
|
|
|
|
assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(State.DL) &&
|
|
|
|
"Expected inlined-at fields to agree");
|
|
|
|
auto MIB = buildInstr(TargetOpcode::DBG_LABEL);
|
|
|
|
|
|
|
|
return MIB.addMetadata(Label);
|
|
|
|
}
|
|
|
|
|
2019-08-28 03:54:27 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildDynStackAlloc(const DstOp &Res,
|
|
|
|
const SrcOp &Size,
|
2020-04-02 17:15:06 +08:00
|
|
|
Align Alignment) {
|
2019-08-28 03:54:27 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).isPointer() && "expected ptr dst type");
|
|
|
|
auto MIB = buildInstr(TargetOpcode::G_DYN_STACKALLOC);
|
|
|
|
Res.addDefToMIB(*getMRI(), MIB);
|
|
|
|
Size.addSrcToMIB(MIB);
|
2020-04-02 17:15:06 +08:00
|
|
|
MIB.addImm(Alignment.value());
|
2019-08-28 03:54:27 +08:00
|
|
|
return MIB;
|
|
|
|
}
|
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFrameIndex(const DstOp &Res,
|
|
|
|
int Idx) {
|
|
|
|
assert(Res.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
|
|
|
|
auto MIB = buildInstr(TargetOpcode::G_FRAME_INDEX);
|
|
|
|
Res.addDefToMIB(*getMRI(), MIB);
|
|
|
|
MIB.addFrameIndex(Idx);
|
|
|
|
return MIB;
|
2016-07-23 00:59:52 +08:00
|
|
|
}
|
2016-07-23 04:03:43 +08:00
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildGlobalValue(const DstOp &Res,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
const GlobalValue *GV) {
|
2019-07-09 00:27:47 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
|
|
|
|
assert(Res.getLLTTy(*getMRI()).getAddressSpace() ==
|
2016-09-12 20:10:41 +08:00
|
|
|
GV->getType()->getAddressSpace() &&
|
|
|
|
"address space mismatch");
|
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
auto MIB = buildInstr(TargetOpcode::G_GLOBAL_VALUE);
|
|
|
|
Res.addDefToMIB(*getMRI(), MIB);
|
|
|
|
MIB.addGlobalAddress(GV);
|
|
|
|
return MIB;
|
2016-09-12 20:10:41 +08:00
|
|
|
}
|
|
|
|
|
2019-06-12 03:58:06 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildJumpTable(const LLT PtrTy,
|
|
|
|
unsigned JTI) {
|
|
|
|
return buildInstr(TargetOpcode::G_JUMP_TABLE, {PtrTy}, {})
|
|
|
|
.addJumpTableIndex(JTI);
|
|
|
|
}
|
|
|
|
|
2020-08-11 17:50:58 +08:00
|
|
|
void MachineIRBuilder::validateUnaryOp(const LLT Res, const LLT Op0) {
|
|
|
|
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
|
|
|
|
assert((Res == Op0) && "type mismatch");
|
|
|
|
}
|
|
|
|
|
2020-02-14 03:30:50 +08:00
|
|
|
void MachineIRBuilder::validateBinaryOp(const LLT Res, const LLT Op0,
|
|
|
|
const LLT Op1) {
|
2018-12-12 06:07:06 +08:00
|
|
|
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
assert((Res == Op0 && Res == Op1) && "type mismatch");
|
2017-07-05 19:02:31 +08:00
|
|
|
}
|
|
|
|
|
2020-02-14 03:30:50 +08:00
|
|
|
void MachineIRBuilder::validateShiftOp(const LLT Res, const LLT Op0,
|
|
|
|
const LLT Op1) {
|
2019-02-08 03:37:44 +08:00
|
|
|
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
|
|
|
|
assert((Res == Op0) && "type mismatch");
|
|
|
|
}
|
|
|
|
|
[globalisel] Rename G_GEP to G_PTR_ADD
Summary:
G_GEP is rather poorly named. It's a simple pointer+scalar addition and
doesn't support any of the complexities of getelementptr. I therefore
propose that we rename it. There's a G_PTR_MASK so let's follow that
convention and go with G_PTR_ADD
Reviewers: volkan, aditya_nandakumar, bogner, rovka, arsenm
Subscribers: sdardis, jvesely, wdng, nhaehnle, hiraditya, jrtc27, atanasyan, arphaman, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69734
2019-11-02 04:18:00 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildPtrAdd(const DstOp &Res,
|
|
|
|
const SrcOp &Op0,
|
|
|
|
const SrcOp &Op1) {
|
2020-01-25 11:57:49 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).getScalarType().isPointer() &&
|
2019-07-09 00:27:47 +08:00
|
|
|
Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch");
|
2020-01-25 11:57:49 +08:00
|
|
|
assert(Op1.getLLTTy(*getMRI()).getScalarType().isScalar() && "invalid offset type");
|
2016-09-12 19:20:22 +08:00
|
|
|
|
[globalisel] Rename G_GEP to G_PTR_ADD
Summary:
G_GEP is rather poorly named. It's a simple pointer+scalar addition and
doesn't support any of the complexities of getelementptr. I therefore
propose that we rename it. There's a G_PTR_MASK so let's follow that
convention and go with G_PTR_ADD
Reviewers: volkan, aditya_nandakumar, bogner, rovka, arsenm
Subscribers: sdardis, jvesely, wdng, nhaehnle, hiraditya, jrtc27, atanasyan, arphaman, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69734
2019-11-02 04:18:00 +08:00
|
|
|
return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1});
|
2016-09-12 19:20:22 +08:00
|
|
|
}
|
|
|
|
|
[globalisel][legalizer] G_LOAD/G_STORE NarrowScalar should not emit G_GEP x, 0.
Summary:
When legalizing G_LOAD/G_STORE using NarrowScalar, we should avoid emitting
%0 = G_CONSTANT ty 0
%1 = G_GEP %x, %0
since it's cheaper to not emit the redundant instructions than it is to fold them
away later.
Reviewers: qcolombet, t.p.northover, ab, rovka, aditya_nandakumar, kristof.beyls
Reviewed By: qcolombet
Subscribers: javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D32746
llvm-svn: 305340
2017-06-14 07:42:32 +08:00
|
|
|
Optional<MachineInstrBuilder>
|
[globalisel] Rename G_GEP to G_PTR_ADD
Summary:
G_GEP is rather poorly named. It's a simple pointer+scalar addition and
doesn't support any of the complexities of getelementptr. I therefore
propose that we rename it. There's a G_PTR_MASK so let's follow that
convention and go with G_PTR_ADD
Reviewers: volkan, aditya_nandakumar, bogner, rovka, arsenm
Subscribers: sdardis, jvesely, wdng, nhaehnle, hiraditya, jrtc27, atanasyan, arphaman, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69734
2019-11-02 04:18:00 +08:00
|
|
|
MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0,
|
2020-02-14 03:30:50 +08:00
|
|
|
const LLT ValueTy, uint64_t Value) {
|
[globalisel][legalizer] G_LOAD/G_STORE NarrowScalar should not emit G_GEP x, 0.
Summary:
When legalizing G_LOAD/G_STORE using NarrowScalar, we should avoid emitting
%0 = G_CONSTANT ty 0
%1 = G_GEP %x, %0
since it's cheaper to not emit the redundant instructions than it is to fold them
away later.
Reviewers: qcolombet, t.p.northover, ab, rovka, aditya_nandakumar, kristof.beyls
Reviewed By: qcolombet
Subscribers: javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D32746
llvm-svn: 305340
2017-06-14 07:42:32 +08:00
|
|
|
assert(Res == 0 && "Res is a result argument");
|
|
|
|
assert(ValueTy.isScalar() && "invalid offset type");
|
|
|
|
|
|
|
|
if (Value == 0) {
|
|
|
|
Res = Op0;
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2018-04-10 01:30:56 +08:00
|
|
|
Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0));
|
2019-04-15 13:04:20 +08:00
|
|
|
auto Cst = buildConstant(ValueTy, Value);
|
[globalisel] Rename G_GEP to G_PTR_ADD
Summary:
G_GEP is rather poorly named. It's a simple pointer+scalar addition and
doesn't support any of the complexities of getelementptr. I therefore
propose that we rename it. There's a G_PTR_MASK so let's follow that
convention and go with G_PTR_ADD
Reviewers: volkan, aditya_nandakumar, bogner, rovka, arsenm
Subscribers: sdardis, jvesely, wdng, nhaehnle, hiraditya, jrtc27, atanasyan, arphaman, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69734
2019-11-02 04:18:00 +08:00
|
|
|
return buildPtrAdd(Res, Op0, Cst.getReg(0));
|
[globalisel][legalizer] G_LOAD/G_STORE NarrowScalar should not emit G_GEP x, 0.
Summary:
When legalizing G_LOAD/G_STORE using NarrowScalar, we should avoid emitting
%0 = G_CONSTANT ty 0
%1 = G_GEP %x, %0
since it's cheaper to not emit the redundant instructions than it is to fold them
away later.
Reviewers: qcolombet, t.p.northover, ab, rovka, aditya_nandakumar, kristof.beyls
Reviewed By: qcolombet
Subscribers: javed.absar, llvm-commits, igorb
Differential Revision: https://reviews.llvm.org/D32746
llvm-svn: 305340
2017-06-14 07:42:32 +08:00
|
|
|
}
|
|
|
|
|
2020-05-16 06:33:01 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res,
|
|
|
|
const SrcOp &Op0,
|
|
|
|
uint32_t NumBits) {
|
|
|
|
LLT PtrTy = Res.getLLTTy(*getMRI());
|
|
|
|
LLT MaskTy = LLT::scalar(PtrTy.getSizeInBits());
|
|
|
|
Register MaskReg = getMRI()->createGenericVirtualRegister(MaskTy);
|
2020-05-31 04:03:16 +08:00
|
|
|
buildConstant(MaskReg, maskTrailingZeros<uint64_t>(NumBits));
|
2020-05-16 06:33:01 +08:00
|
|
|
return buildPtrMask(Res, Op0, MaskReg);
|
2017-02-15 04:56:18 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
|
2016-09-09 19:46:34 +08:00
|
|
|
return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
|
2016-07-27 00:45:26 +08:00
|
|
|
}
|
|
|
|
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBrIndirect(Register Tgt) {
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(getMRI()->getType(Tgt).isPointer() && "invalid branch destination");
|
2017-01-30 17:13:18 +08:00
|
|
|
return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
|
|
|
|
}
|
|
|
|
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBrJT(Register TablePtr,
|
2019-06-15 01:55:48 +08:00
|
|
|
unsigned JTI,
|
2019-06-28 09:16:41 +08:00
|
|
|
Register IndexReg) {
|
2019-06-15 01:55:48 +08:00
|
|
|
assert(getMRI()->getType(TablePtr).isPointer() &&
|
|
|
|
"Table reg must be a pointer");
|
|
|
|
return buildInstr(TargetOpcode::G_BRJT)
|
|
|
|
.addUse(TablePtr)
|
|
|
|
.addJumpTableIndex(JTI)
|
|
|
|
.addUse(IndexReg);
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildCopy(const DstOp &Res,
|
2019-03-19 03:20:10 +08:00
|
|
|
const SrcOp &Op) {
|
|
|
|
return buildInstr(TargetOpcode::COPY, Res, Op);
|
2016-07-27 00:45:30 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
|
|
|
|
const ConstantInt &Val) {
|
|
|
|
LLT Ty = Res.getLLTTy(*getMRI());
|
2019-01-23 05:31:02 +08:00
|
|
|
LLT EltTy = Ty.getScalarType();
|
2019-02-05 03:15:50 +08:00
|
|
|
assert(EltTy.getScalarSizeInBits() == Val.getBitWidth() &&
|
|
|
|
"creating constant with the wrong size");
|
2019-01-23 05:31:02 +08:00
|
|
|
|
|
|
|
if (Ty.isVector()) {
|
2019-02-05 03:15:50 +08:00
|
|
|
auto Const = buildInstr(TargetOpcode::G_CONSTANT)
|
|
|
|
.addDef(getMRI()->createGenericVirtualRegister(EltTy))
|
|
|
|
.addCImm(&Val);
|
|
|
|
return buildSplatVector(Res, Const);
|
2019-01-23 05:31:02 +08:00
|
|
|
}
|
2016-12-06 05:47:07 +08:00
|
|
|
|
2019-02-05 03:15:50 +08:00
|
|
|
auto Const = buildInstr(TargetOpcode::G_CONSTANT);
|
2020-04-28 02:24:36 +08:00
|
|
|
Const->setDebugLoc(DebugLoc());
|
2019-02-05 03:15:50 +08:00
|
|
|
Res.addDefToMIB(*getMRI(), Const);
|
|
|
|
Const.addCImm(&Val);
|
|
|
|
return Const;
|
2016-12-06 05:47:07 +08:00
|
|
|
}
|
2016-09-09 19:46:58 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
|
|
|
|
int64_t Val) {
|
2018-04-10 01:30:56 +08:00
|
|
|
auto IntN = IntegerType::get(getMF().getFunction().getContext(),
|
2019-02-05 03:15:50 +08:00
|
|
|
Res.getLLTTy(*getMRI()).getScalarSizeInBits());
|
2016-12-06 05:47:07 +08:00
|
|
|
ConstantInt *CI = ConstantInt::get(IntN, Val, true);
|
|
|
|
return buildConstant(Res, *CI);
|
2016-08-05 04:54:13 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
|
|
|
|
const ConstantFP &Val) {
|
2019-01-23 05:31:02 +08:00
|
|
|
LLT Ty = Res.getLLTTy(*getMRI());
|
2019-02-05 03:15:50 +08:00
|
|
|
LLT EltTy = Ty.getScalarType();
|
|
|
|
|
|
|
|
assert(APFloat::getSizeInBits(Val.getValueAPF().getSemantics())
|
|
|
|
== EltTy.getSizeInBits() &&
|
|
|
|
"creating fconstant with the wrong size");
|
2019-01-23 05:31:02 +08:00
|
|
|
|
|
|
|
assert(!Ty.isPointer() && "invalid operand type");
|
|
|
|
|
|
|
|
if (Ty.isVector()) {
|
2019-02-05 03:15:50 +08:00
|
|
|
auto Const = buildInstr(TargetOpcode::G_FCONSTANT)
|
|
|
|
.addDef(getMRI()->createGenericVirtualRegister(EltTy))
|
|
|
|
.addFPImm(&Val);
|
|
|
|
|
|
|
|
return buildSplatVector(Res, Const);
|
2019-01-23 05:31:02 +08:00
|
|
|
}
|
2016-09-09 19:46:58 +08:00
|
|
|
|
2019-02-05 03:15:50 +08:00
|
|
|
auto Const = buildInstr(TargetOpcode::G_FCONSTANT);
|
2020-05-12 07:21:26 +08:00
|
|
|
Const->setDebugLoc(DebugLoc());
|
2019-02-05 03:15:50 +08:00
|
|
|
Res.addDefToMIB(*getMRI(), Const);
|
|
|
|
Const.addFPImm(&Val);
|
|
|
|
return Const;
|
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
|
|
|
|
const APInt &Val) {
|
|
|
|
ConstantInt *CI = ConstantInt::get(getMF().getFunction().getContext(), Val);
|
|
|
|
return buildConstant(Res, *CI);
|
2016-08-20 04:09:15 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
|
|
|
|
double Val) {
|
|
|
|
LLT DstTy = Res.getLLTTy(*getMRI());
|
2018-04-10 01:30:56 +08:00
|
|
|
auto &Ctx = getMF().getFunction().getContext();
|
2018-03-10 01:31:51 +08:00
|
|
|
auto *CFP =
|
2019-02-05 03:15:50 +08:00
|
|
|
ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getScalarSizeInBits()));
|
2018-03-10 01:31:51 +08:00
|
|
|
return buildFConstant(Res, *CFP);
|
|
|
|
}
|
|
|
|
|
2019-05-16 12:09:06 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
|
|
|
|
const APFloat &Val) {
|
|
|
|
auto &Ctx = getMF().getFunction().getContext();
|
|
|
|
auto *CFP = ConstantFP::get(Ctx, Val);
|
|
|
|
return buildFConstant(Res, *CFP);
|
|
|
|
}
|
|
|
|
|
2020-08-05 01:55:27 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineBasicBlock &Dest) {
|
2020-08-05 01:55:27 +08:00
|
|
|
assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
|
2016-09-09 19:46:58 +08:00
|
|
|
|
2020-08-05 01:55:27 +08:00
|
|
|
auto MIB = buildInstr(TargetOpcode::G_BRCOND);
|
|
|
|
Tst.addSrcToMIB(MIB);
|
|
|
|
MIB.addMBB(&Dest);
|
|
|
|
return MIB;
|
2016-07-30 01:58:00 +08:00
|
|
|
}
|
|
|
|
|
2020-07-27 09:25:10 +08:00
|
|
|
MachineInstrBuilder
|
|
|
|
MachineIRBuilder::buildLoad(const DstOp &Dst, const SrcOp &Addr,
|
|
|
|
MachinePointerInfo PtrInfo, Align Alignment,
|
|
|
|
MachineMemOperand::Flags MMOFlags,
|
|
|
|
const AAMDNodes &AAInfo) {
|
|
|
|
MMOFlags |= MachineMemOperand::MOLoad;
|
|
|
|
assert((MMOFlags & MachineMemOperand::MOStore) == 0);
|
|
|
|
|
|
|
|
uint64_t Size = MemoryLocation::getSizeOrUnknown(
|
|
|
|
TypeSize::Fixed(Dst.getLLTTy(*getMRI()).getSizeInBytes()));
|
|
|
|
MachineMemOperand *MMO =
|
|
|
|
getMF().getMachineMemOperand(PtrInfo, MMOFlags, Size, Alignment, AAInfo);
|
|
|
|
return buildLoad(Dst, Addr, *MMO);
|
[globalisel][legalizerinfo] Introduce dedicated extending loads and add lowerings for them
Summary:
Previously, a extending load was represented at (G_*EXT (G_LOAD x)).
This had a few drawbacks:
* G_LOAD had to be legal for all sizes you could extend from, even if
registers didn't naturally hold those sizes.
* All sizes you could extend from had to be allocatable just in case the
extend went missing (e.g. by optimization).
* At minimum, G_*EXT and G_TRUNC had to be legal for these sizes. As we
improve optimization of extends and truncates, this legality requirement
would spread without considerable care w.r.t when certain combines were
permitted.
* The SelectionDAG importer required some ugly and fragile pattern
rewriting to translate patterns into this style.
This patch begins changing the representation to:
* (G_[SZ]EXTLOAD x)
* (G_LOAD x) any-extends when MMO.getSize() * 8 < ResultTy.getSizeInBits()
which resolves these issues by allowing targets to work entirely in their
native register sizes, and by having a more direct translation from
SelectionDAG patterns.
This patch introduces the new generic instructions and new variation on
G_LOAD and adds lowering for them to convert back to the existing
representations.
Depends on D45466
Reviewers: ab, aditya_nandakumar, bogner, rtereshin, volkan, rovka, aemerson, javed.absar
Reviewed By: aemerson
Subscribers: aemerson, kristof.beyls, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D45540
llvm-svn: 331115
2018-04-29 02:14:50 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildLoadInstr(unsigned Opcode,
|
2019-07-09 00:27:47 +08:00
|
|
|
const DstOp &Res,
|
|
|
|
const SrcOp &Addr,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineMemOperand &MMO) {
|
2019-07-09 00:27:47 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).isValid() && "invalid operand type");
|
|
|
|
assert(Addr.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
|
2016-09-09 19:46:58 +08:00
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
auto MIB = buildInstr(Opcode);
|
|
|
|
Res.addDefToMIB(*getMRI(), MIB);
|
|
|
|
Addr.addSrcToMIB(MIB);
|
|
|
|
MIB.addMemOperand(&MMO);
|
|
|
|
return MIB;
|
2016-07-27 04:23:26 +08:00
|
|
|
}
|
|
|
|
|
2020-05-31 08:28:36 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildLoadFromOffset(
|
|
|
|
const DstOp &Dst, const SrcOp &BasePtr,
|
|
|
|
MachineMemOperand &BaseMMO, int64_t Offset) {
|
|
|
|
LLT LoadTy = Dst.getLLTTy(*getMRI());
|
|
|
|
MachineMemOperand *OffsetMMO =
|
|
|
|
getMF().getMachineMemOperand(&BaseMMO, Offset, LoadTy.getSizeInBytes());
|
|
|
|
|
|
|
|
if (Offset == 0) // This may be a size or type changing load.
|
|
|
|
return buildLoad(Dst, BasePtr, *OffsetMMO);
|
|
|
|
|
|
|
|
LLT PtrTy = BasePtr.getLLTTy(*getMRI());
|
|
|
|
LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
|
|
|
|
auto ConstOffset = buildConstant(OffsetTy, Offset);
|
|
|
|
auto Ptr = buildPtrAdd(PtrTy, BasePtr, ConstOffset);
|
|
|
|
return buildLoad(Dst, Ptr, *OffsetMMO);
|
|
|
|
}
|
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildStore(const SrcOp &Val,
|
|
|
|
const SrcOp &Addr,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineMemOperand &MMO) {
|
2019-07-09 00:27:47 +08:00
|
|
|
assert(Val.getLLTTy(*getMRI()).isValid() && "invalid operand type");
|
|
|
|
assert(Addr.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
|
2016-09-09 19:46:58 +08:00
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
auto MIB = buildInstr(TargetOpcode::G_STORE);
|
|
|
|
Val.addSrcToMIB(MIB);
|
|
|
|
Addr.addSrcToMIB(MIB);
|
|
|
|
MIB.addMemOperand(&MMO);
|
|
|
|
return MIB;
|
2016-07-27 04:23:26 +08:00
|
|
|
}
|
|
|
|
|
2020-07-27 09:25:10 +08:00
|
|
|
MachineInstrBuilder
|
|
|
|
MachineIRBuilder::buildStore(const SrcOp &Val, const SrcOp &Addr,
|
|
|
|
MachinePointerInfo PtrInfo, Align Alignment,
|
|
|
|
MachineMemOperand::Flags MMOFlags,
|
|
|
|
const AAMDNodes &AAInfo) {
|
|
|
|
MMOFlags |= MachineMemOperand::MOStore;
|
|
|
|
assert((MMOFlags & MachineMemOperand::MOLoad) == 0);
|
|
|
|
|
|
|
|
uint64_t Size = MemoryLocation::getSizeOrUnknown(
|
|
|
|
TypeSize::Fixed(Val.getLLTTy(*getMRI()).getSizeInBytes()));
|
|
|
|
MachineMemOperand *MMO =
|
|
|
|
getMF().getMachineMemOperand(PtrInfo, MMOFlags, Size, Alignment, AAInfo);
|
|
|
|
return buildStore(Val, Addr, *MMO);
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildAnyExt(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
|
|
|
return buildInstr(TargetOpcode::G_ANYEXT, Res, Op);
|
2016-08-05 02:35:11 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildSExt(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
|
|
|
return buildInstr(TargetOpcode::G_SEXT, Res, Op);
|
2016-08-24 05:01:26 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildZExt(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
|
|
|
return buildInstr(TargetOpcode::G_ZEXT, Res, Op);
|
2016-08-24 05:01:26 +08:00
|
|
|
}
|
|
|
|
|
2019-01-30 10:57:43 +08:00
|
|
|
unsigned MachineIRBuilder::getBoolExtOp(bool IsVec, bool IsFP) const {
|
|
|
|
const auto *TLI = getMF().getSubtarget().getTargetLowering();
|
|
|
|
switch (TLI->getBooleanContents(IsVec, IsFP)) {
|
|
|
|
case TargetLoweringBase::ZeroOrNegativeOneBooleanContent:
|
|
|
|
return TargetOpcode::G_SEXT;
|
|
|
|
case TargetLoweringBase::ZeroOrOneBooleanContent:
|
|
|
|
return TargetOpcode::G_ZEXT;
|
|
|
|
default:
|
|
|
|
return TargetOpcode::G_ANYEXT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBoolExt(const DstOp &Res,
|
|
|
|
const SrcOp &Op,
|
|
|
|
bool IsFP) {
|
|
|
|
unsigned ExtOp = getBoolExtOp(getMRI()->getType(Op.getReg()).isVector(), IsFP);
|
|
|
|
return buildInstr(ExtOp, Res, Op);
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc,
|
|
|
|
const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
2017-08-25 12:57:27 +08:00
|
|
|
assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
|
|
|
|
TargetOpcode::G_SEXT == ExtOpc) &&
|
|
|
|
"Expecting Extending Opc");
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).isScalar() ||
|
|
|
|
Res.getLLTTy(*getMRI()).isVector());
|
|
|
|
assert(Res.getLLTTy(*getMRI()).isScalar() ==
|
|
|
|
Op.getLLTTy(*getMRI()).isScalar());
|
2017-06-28 06:45:35 +08:00
|
|
|
|
2016-09-12 19:20:22 +08:00
|
|
|
unsigned Opcode = TargetOpcode::COPY;
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
if (Res.getLLTTy(*getMRI()).getSizeInBits() >
|
|
|
|
Op.getLLTTy(*getMRI()).getSizeInBits())
|
2017-08-25 12:57:27 +08:00
|
|
|
Opcode = ExtOpc;
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
else if (Res.getLLTTy(*getMRI()).getSizeInBits() <
|
|
|
|
Op.getLLTTy(*getMRI()).getSizeInBits())
|
2016-09-12 19:20:22 +08:00
|
|
|
Opcode = TargetOpcode::G_TRUNC;
|
2017-06-28 06:45:35 +08:00
|
|
|
else
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()) == Op.getLLTTy(*getMRI()));
|
2016-09-12 19:20:22 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
return buildInstr(Opcode, Res, Op);
|
2016-09-12 19:20:22 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
2017-08-25 12:57:27 +08:00
|
|
|
return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
|
|
|
|
}
|
2017-06-28 06:45:35 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
2017-08-25 12:57:27 +08:00
|
|
|
return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
|
|
|
|
}
|
2017-02-04 02:22:45 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildAnyExtOrTrunc(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
2017-08-25 12:57:27 +08:00
|
|
|
return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
|
2017-02-04 02:22:45 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildCast(const DstOp &Dst,
|
|
|
|
const SrcOp &Src) {
|
|
|
|
LLT SrcTy = Src.getLLTTy(*getMRI());
|
|
|
|
LLT DstTy = Dst.getLLTTy(*getMRI());
|
2017-03-07 03:04:17 +08:00
|
|
|
if (SrcTy == DstTy)
|
|
|
|
return buildCopy(Dst, Src);
|
|
|
|
|
|
|
|
unsigned Opcode;
|
|
|
|
if (SrcTy.isPointer() && DstTy.isScalar())
|
|
|
|
Opcode = TargetOpcode::G_PTRTOINT;
|
|
|
|
else if (DstTy.isPointer() && SrcTy.isScalar())
|
|
|
|
Opcode = TargetOpcode::G_INTTOPTR;
|
|
|
|
else {
|
|
|
|
assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
|
|
|
|
Opcode = TargetOpcode::G_BITCAST;
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
return buildInstr(Opcode, Dst, Src);
|
2017-03-07 03:04:17 +08:00
|
|
|
}
|
|
|
|
|
2019-02-19 06:39:22 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildExtract(const DstOp &Dst,
|
|
|
|
const SrcOp &Src,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
uint64_t Index) {
|
2019-02-19 06:39:22 +08:00
|
|
|
LLT SrcTy = Src.getLLTTy(*getMRI());
|
|
|
|
LLT DstTy = Dst.getLLTTy(*getMRI());
|
|
|
|
|
2016-09-09 19:46:58 +08:00
|
|
|
#ifndef NDEBUG
|
2019-02-19 06:39:22 +08:00
|
|
|
assert(SrcTy.isValid() && "invalid operand type");
|
|
|
|
assert(DstTy.isValid() && "invalid operand type");
|
|
|
|
assert(Index + DstTy.getSizeInBits() <= SrcTy.getSizeInBits() &&
|
2017-03-07 07:50:28 +08:00
|
|
|
"extracting off end of register");
|
2016-09-09 19:46:58 +08:00
|
|
|
#endif
|
|
|
|
|
2019-02-19 06:39:22 +08:00
|
|
|
if (DstTy.getSizeInBits() == SrcTy.getSizeInBits()) {
|
2017-03-07 07:50:28 +08:00
|
|
|
assert(Index == 0 && "insertion past the end of a register");
|
2019-02-19 06:39:22 +08:00
|
|
|
return buildCast(Dst, Src);
|
2017-03-07 07:50:28 +08:00
|
|
|
}
|
2016-08-20 02:32:14 +08:00
|
|
|
|
2019-02-19 06:39:22 +08:00
|
|
|
auto Extract = buildInstr(TargetOpcode::G_EXTRACT);
|
|
|
|
Dst.addDefToMIB(*getMRI(), Extract);
|
|
|
|
Src.addSrcToMIB(Extract);
|
|
|
|
Extract.addImm(Index);
|
|
|
|
return Extract;
|
2016-07-23 04:03:43 +08:00
|
|
|
}
|
|
|
|
|
2019-06-24 23:50:29 +08:00
|
|
|
void MachineIRBuilder::buildSequence(Register Res, ArrayRef<Register> Ops,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
ArrayRef<uint64_t> Indices) {
|
2016-09-09 19:46:58 +08:00
|
|
|
#ifndef NDEBUG
|
2016-09-09 19:46:34 +08:00
|
|
|
assert(Ops.size() == Indices.size() && "incompatible args");
|
2016-08-20 02:32:14 +08:00
|
|
|
assert(!Ops.empty() && "invalid trivial sequence");
|
2020-04-13 19:46:41 +08:00
|
|
|
assert(llvm::is_sorted(Indices) &&
|
2016-08-31 04:51:25 +08:00
|
|
|
"sequence offsets must be in ascending order");
|
2016-08-20 01:17:06 +08:00
|
|
|
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(getMRI()->getType(Res).isValid() && "invalid operand type");
|
2016-09-09 19:46:58 +08:00
|
|
|
for (auto Op : Ops)
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(getMRI()->getType(Op).isValid() && "invalid operand type");
|
2016-09-09 19:46:58 +08:00
|
|
|
#endif
|
|
|
|
|
2018-04-10 01:30:56 +08:00
|
|
|
LLT ResTy = getMRI()->getType(Res);
|
|
|
|
LLT OpTy = getMRI()->getType(Ops[0]);
|
2017-06-24 00:15:37 +08:00
|
|
|
unsigned OpSize = OpTy.getSizeInBits();
|
|
|
|
bool MaybeMerge = true;
|
2016-08-20 01:17:06 +08:00
|
|
|
for (unsigned i = 0; i < Ops.size(); ++i) {
|
2018-04-10 01:30:56 +08:00
|
|
|
if (getMRI()->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) {
|
2017-06-24 00:15:37 +08:00
|
|
|
MaybeMerge = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) {
|
|
|
|
buildMerge(Res, Ops);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-06-24 23:50:29 +08:00
|
|
|
Register ResIn = getMRI()->createGenericVirtualRegister(ResTy);
|
2017-06-24 00:15:37 +08:00
|
|
|
buildUndef(ResIn);
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < Ops.size(); ++i) {
|
2019-06-24 23:50:29 +08:00
|
|
|
Register ResOut = i + 1 == Ops.size()
|
2018-04-10 01:30:56 +08:00
|
|
|
? Res
|
|
|
|
: getMRI()->createGenericVirtualRegister(ResTy);
|
2017-06-24 00:15:37 +08:00
|
|
|
buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
|
|
|
|
ResIn = ResOut;
|
2016-08-20 01:17:06 +08:00
|
|
|
}
|
2017-03-04 06:46:09 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildUndef(const DstOp &Res) {
|
|
|
|
return buildInstr(TargetOpcode::G_IMPLICIT_DEF, {Res}, {});
|
2017-03-07 02:36:40 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildMerge(const DstOp &Res,
|
2019-06-24 23:50:29 +08:00
|
|
|
ArrayRef<Register> Ops) {
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
// Unfortunately to convert from ArrayRef<LLT> to ArrayRef<SrcOp>,
|
|
|
|
// we need some temporary storage for the DstOp objects. Here we use a
|
|
|
|
// sufficiently large SmallVector to not go through the heap.
|
|
|
|
SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
|
2019-07-18 04:22:44 +08:00
|
|
|
assert(TmpVec.size() > 1);
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, TmpVec);
|
2017-03-04 06:46:09 +08:00
|
|
|
}
|
|
|
|
|
2020-02-08 00:38:01 +08:00
|
|
|
MachineInstrBuilder
|
|
|
|
MachineIRBuilder::buildMerge(const DstOp &Res,
|
|
|
|
std::initializer_list<SrcOp> Ops) {
|
|
|
|
assert(Ops.size() > 1);
|
|
|
|
return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, Ops);
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<LLT> Res,
|
|
|
|
const SrcOp &Op) {
|
|
|
|
// Unfortunately to convert from ArrayRef<LLT> to ArrayRef<DstOp>,
|
|
|
|
// we need some temporary storage for the DstOp objects. Here we use a
|
|
|
|
// sufficiently large SmallVector to not go through the heap.
|
|
|
|
SmallVector<DstOp, 8> TmpVec(Res.begin(), Res.end());
|
2019-07-18 04:22:44 +08:00
|
|
|
assert(TmpVec.size() > 1);
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
return buildInstr(TargetOpcode::G_UNMERGE_VALUES, TmpVec, Op);
|
|
|
|
}
|
2017-03-04 06:46:09 +08:00
|
|
|
|
2019-04-05 22:03:07 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildUnmerge(LLT Res,
|
|
|
|
const SrcOp &Op) {
|
|
|
|
unsigned NumReg = Op.getLLTTy(*getMRI()).getSizeInBits() / Res.getSizeInBits();
|
2019-06-24 23:50:29 +08:00
|
|
|
SmallVector<Register, 8> TmpVec;
|
2019-04-05 22:03:07 +08:00
|
|
|
for (unsigned I = 0; I != NumReg; ++I)
|
|
|
|
TmpVec.push_back(getMRI()->createGenericVirtualRegister(Res));
|
|
|
|
return buildUnmerge(TmpVec, Op);
|
|
|
|
}
|
|
|
|
|
2019-06-24 23:50:29 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<Register> Res,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
const SrcOp &Op) {
|
2019-06-28 09:16:41 +08:00
|
|
|
// Unfortunately to convert from ArrayRef<Register> to ArrayRef<DstOp>,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
// we need some temporary storage for the DstOp objects. Here we use a
|
|
|
|
// sufficiently large SmallVector to not go through the heap.
|
|
|
|
SmallVector<DstOp, 8> TmpVec(Res.begin(), Res.end());
|
2019-07-18 04:22:44 +08:00
|
|
|
assert(TmpVec.size() > 1);
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
return buildInstr(TargetOpcode::G_UNMERGE_VALUES, TmpVec, Op);
|
2016-07-23 04:03:43 +08:00
|
|
|
}
|
2016-07-30 06:32:36 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBuildVector(const DstOp &Res,
|
2019-06-24 23:50:29 +08:00
|
|
|
ArrayRef<Register> Ops) {
|
2019-06-28 09:16:41 +08:00
|
|
|
// Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
// we need some temporary storage for the DstOp objects. Here we use a
|
|
|
|
// sufficiently large SmallVector to not go through the heap.
|
|
|
|
SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
|
|
|
|
return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
|
2018-12-06 07:53:30 +08:00
|
|
|
}
|
|
|
|
|
2019-02-05 03:15:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildSplatVector(const DstOp &Res,
|
|
|
|
const SrcOp &Src) {
|
|
|
|
SmallVector<SrcOp, 8> TmpVec(Res.getLLTTy(*getMRI()).getNumElements(), Src);
|
|
|
|
return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
|
|
|
|
}
|
|
|
|
|
2018-12-06 07:53:30 +08:00
|
|
|
MachineInstrBuilder
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineIRBuilder::buildBuildVectorTrunc(const DstOp &Res,
|
2019-06-24 23:50:29 +08:00
|
|
|
ArrayRef<Register> Ops) {
|
2019-06-28 09:16:41 +08:00
|
|
|
// Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
// we need some temporary storage for the DstOp objects. Here we use a
|
|
|
|
// sufficiently large SmallVector to not go through the heap.
|
|
|
|
SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
|
|
|
|
return buildInstr(TargetOpcode::G_BUILD_VECTOR_TRUNC, Res, TmpVec);
|
2018-12-06 07:53:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder
|
2019-06-24 23:50:29 +08:00
|
|
|
MachineIRBuilder::buildConcatVectors(const DstOp &Res, ArrayRef<Register> Ops) {
|
2019-06-28 09:16:41 +08:00
|
|
|
// Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
// we need some temporary storage for the DstOp objects. Here we use a
|
|
|
|
// sufficiently large SmallVector to not go through the heap.
|
|
|
|
SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
|
|
|
|
return buildInstr(TargetOpcode::G_CONCAT_VECTORS, Res, TmpVec);
|
2018-12-06 07:53:30 +08:00
|
|
|
}
|
|
|
|
|
[GlobalISel] Tidy up unnecessary calls to createGenericVirtualRegister
Summary:
As a side effect some redundant copies of constant values are removed by
CSEMIRBuilder.
Reviewers: aemerson, arsenm, dsanders, aditya_nandakumar
Subscribers: sdardis, jvesely, wdng, nhaehnle, rovka, hiraditya, jrtc27, atanasyan, volkan, Petar.Avramovic, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73789
2020-01-31 20:40:31 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildInsert(const DstOp &Res,
|
|
|
|
const SrcOp &Src,
|
|
|
|
const SrcOp &Op,
|
|
|
|
unsigned Index) {
|
|
|
|
assert(Index + Op.getLLTTy(*getMRI()).getSizeInBits() <=
|
|
|
|
Res.getLLTTy(*getMRI()).getSizeInBits() &&
|
2017-06-28 06:45:35 +08:00
|
|
|
"insertion past the end of a register");
|
|
|
|
|
[GlobalISel] Tidy up unnecessary calls to createGenericVirtualRegister
Summary:
As a side effect some redundant copies of constant values are removed by
CSEMIRBuilder.
Reviewers: aemerson, arsenm, dsanders, aditya_nandakumar
Subscribers: sdardis, jvesely, wdng, nhaehnle, rovka, hiraditya, jrtc27, atanasyan, volkan, Petar.Avramovic, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73789
2020-01-31 20:40:31 +08:00
|
|
|
if (Res.getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
Op.getLLTTy(*getMRI()).getSizeInBits()) {
|
2017-03-07 03:04:17 +08:00
|
|
|
return buildCast(Res, Op);
|
|
|
|
}
|
|
|
|
|
[GlobalISel] Tidy up unnecessary calls to createGenericVirtualRegister
Summary:
As a side effect some redundant copies of constant values are removed by
CSEMIRBuilder.
Reviewers: aemerson, arsenm, dsanders, aditya_nandakumar
Subscribers: sdardis, jvesely, wdng, nhaehnle, rovka, hiraditya, jrtc27, atanasyan, volkan, Petar.Avramovic, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73789
2020-01-31 20:40:31 +08:00
|
|
|
return buildInstr(TargetOpcode::G_INSERT, Res, {Src, Op, uint64_t(Index)});
|
2017-03-04 07:05:47 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
|
2019-06-24 23:50:29 +08:00
|
|
|
ArrayRef<Register> ResultRegs,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
bool HasSideEffects) {
|
2016-07-30 06:32:36 +08:00
|
|
|
auto MIB =
|
|
|
|
buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
|
2016-09-09 19:46:34 +08:00
|
|
|
: TargetOpcode::G_INTRINSIC);
|
2019-03-14 22:18:56 +08:00
|
|
|
for (unsigned ResultReg : ResultRegs)
|
|
|
|
MIB.addDef(ResultReg);
|
2016-07-30 06:32:36 +08:00
|
|
|
MIB.addIntrinsicID(ID);
|
|
|
|
return MIB;
|
|
|
|
}
|
2016-08-05 02:35:11 +08:00
|
|
|
|
2019-05-16 20:22:56 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
|
|
|
|
ArrayRef<DstOp> Results,
|
|
|
|
bool HasSideEffects) {
|
|
|
|
auto MIB =
|
|
|
|
buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
|
|
|
|
: TargetOpcode::G_INTRINSIC);
|
|
|
|
for (DstOp Result : Results)
|
|
|
|
Result.addDefToMIB(*getMRI(), MIB);
|
|
|
|
MIB.addIntrinsicID(ID);
|
|
|
|
return MIB;
|
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildTrunc(const DstOp &Res,
|
|
|
|
const SrcOp &Op) {
|
|
|
|
return buildInstr(TargetOpcode::G_TRUNC, Res, Op);
|
2016-08-05 02:35:11 +08:00
|
|
|
}
|
2016-08-18 04:25:25 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFPTrunc(const DstOp &Res,
|
AMDGPU/GlobalISel: Legalize FDIV16
Reviewers: arsenm
Reviewed By: arsenm
Subscribers: kzhuravl, jvesely, wdng, nhaehnle, yaxunl, rovka, dstuttard, tpr, t-tye, hiraditya, volkan, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69347
2019-10-23 08:39:26 +08:00
|
|
|
const SrcOp &Op,
|
|
|
|
Optional<unsigned> Flags) {
|
|
|
|
return buildInstr(TargetOpcode::G_FPTRUNC, Res, Op, Flags);
|
2016-08-20 06:40:08 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
|
|
|
|
const DstOp &Res,
|
|
|
|
const SrcOp &Op0,
|
|
|
|
const SrcOp &Op1) {
|
|
|
|
return buildInstr(TargetOpcode::G_ICMP, Res, {Pred, Op0, Op1});
|
2016-08-18 04:25:25 +08:00
|
|
|
}
|
2016-08-20 04:09:07 +08:00
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
|
|
|
|
const DstOp &Res,
|
|
|
|
const SrcOp &Op0,
|
[AMDGPU/GlobalISel] Add llvm.amdgcn.fdiv.fast legalization.
Reviewers: arsenm
Reviewed By: arsenm
Subscribers: volkan, kzhuravl, jvesely, wdng, nhaehnle, yaxunl, rovka, dstuttard, tpr, t-tye, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64966
llvm-svn: 367344
2019-07-31 02:49:16 +08:00
|
|
|
const SrcOp &Op1,
|
|
|
|
Optional<unsigned> Flags) {
|
2016-09-09 19:46:58 +08:00
|
|
|
|
[AMDGPU/GlobalISel] Add llvm.amdgcn.fdiv.fast legalization.
Reviewers: arsenm
Reviewed By: arsenm
Subscribers: volkan, kzhuravl, jvesely, wdng, nhaehnle, yaxunl, rovka, dstuttard, tpr, t-tye, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64966
llvm-svn: 367344
2019-07-31 02:49:16 +08:00
|
|
|
return buildInstr(TargetOpcode::G_FCMP, Res, {Pred, Op0, Op1}, Flags);
|
2016-08-20 04:48:16 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildSelect(const DstOp &Res,
|
|
|
|
const SrcOp &Tst,
|
|
|
|
const SrcOp &Op0,
|
[AMDGPU/GlobalISel] Add llvm.amdgcn.fdiv.fast legalization.
Reviewers: arsenm
Reviewed By: arsenm
Subscribers: volkan, kzhuravl, jvesely, wdng, nhaehnle, yaxunl, rovka, dstuttard, tpr, t-tye, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64966
llvm-svn: 367344
2019-07-31 02:49:16 +08:00
|
|
|
const SrcOp &Op1,
|
|
|
|
Optional<unsigned> Flags) {
|
2016-09-09 19:46:58 +08:00
|
|
|
|
[AMDGPU/GlobalISel] Add llvm.amdgcn.fdiv.fast legalization.
Reviewers: arsenm
Reviewed By: arsenm
Subscribers: volkan, kzhuravl, jvesely, wdng, nhaehnle, yaxunl, rovka, dstuttard, tpr, t-tye, hiraditya, Petar.Avramovic, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64966
llvm-svn: 367344
2019-07-31 02:49:16 +08:00
|
|
|
return buildInstr(TargetOpcode::G_SELECT, {Res}, {Tst, Op0, Op1}, Flags);
|
2016-08-20 04:09:07 +08:00
|
|
|
}
|
2016-08-24 05:01:33 +08:00
|
|
|
|
2018-04-10 01:30:56 +08:00
|
|
|
MachineInstrBuilder
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineIRBuilder::buildInsertVectorElement(const DstOp &Res, const SrcOp &Val,
|
|
|
|
const SrcOp &Elt, const SrcOp &Idx) {
|
|
|
|
return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT, Res, {Val, Elt, Idx});
|
2017-03-11 03:08:28 +08:00
|
|
|
}
|
|
|
|
|
2018-04-10 01:30:56 +08:00
|
|
|
MachineInstrBuilder
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineIRBuilder::buildExtractVectorElement(const DstOp &Res, const SrcOp &Val,
|
|
|
|
const SrcOp &Idx) {
|
|
|
|
return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT, Res, {Val, Idx});
|
2017-03-11 03:08:28 +08:00
|
|
|
}
|
|
|
|
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildAtomicCmpXchgWithSuccess(
|
2019-06-28 09:16:41 +08:00
|
|
|
Register OldValRes, Register SuccessRes, Register Addr, Register CmpVal,
|
|
|
|
Register NewVal, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
LLT OldValResTy = getMRI()->getType(OldValRes);
|
|
|
|
LLT SuccessResTy = getMRI()->getType(SuccessRes);
|
|
|
|
LLT AddrTy = getMRI()->getType(Addr);
|
|
|
|
LLT CmpValTy = getMRI()->getType(CmpVal);
|
|
|
|
LLT NewValTy = getMRI()->getType(NewVal);
|
|
|
|
assert(OldValResTy.isScalar() && "invalid operand type");
|
|
|
|
assert(SuccessResTy.isScalar() && "invalid operand type");
|
|
|
|
assert(AddrTy.isPointer() && "invalid operand type");
|
|
|
|
assert(CmpValTy.isValid() && "invalid operand type");
|
|
|
|
assert(NewValTy.isValid() && "invalid operand type");
|
|
|
|
assert(OldValResTy == CmpValTy && "type mismatch");
|
|
|
|
assert(OldValResTy == NewValTy && "type mismatch");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS)
|
|
|
|
.addDef(OldValRes)
|
|
|
|
.addDef(SuccessRes)
|
|
|
|
.addUse(Addr)
|
|
|
|
.addUse(CmpVal)
|
|
|
|
.addUse(NewVal)
|
|
|
|
.addMemOperand(&MMO);
|
|
|
|
}
|
|
|
|
|
2017-12-01 04:11:42 +08:00
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicCmpXchg(Register OldValRes, Register Addr,
|
|
|
|
Register CmpVal, Register NewVal,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineMemOperand &MMO) {
|
2017-12-01 04:11:42 +08:00
|
|
|
#ifndef NDEBUG
|
2018-04-10 01:30:56 +08:00
|
|
|
LLT OldValResTy = getMRI()->getType(OldValRes);
|
|
|
|
LLT AddrTy = getMRI()->getType(Addr);
|
|
|
|
LLT CmpValTy = getMRI()->getType(CmpVal);
|
|
|
|
LLT NewValTy = getMRI()->getType(NewVal);
|
2017-12-01 04:11:42 +08:00
|
|
|
assert(OldValResTy.isScalar() && "invalid operand type");
|
|
|
|
assert(AddrTy.isPointer() && "invalid operand type");
|
|
|
|
assert(CmpValTy.isValid() && "invalid operand type");
|
|
|
|
assert(NewValTy.isValid() && "invalid operand type");
|
|
|
|
assert(OldValResTy == CmpValTy && "type mismatch");
|
|
|
|
assert(OldValResTy == NewValTy && "type mismatch");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG)
|
|
|
|
.addDef(OldValRes)
|
|
|
|
.addUse(Addr)
|
|
|
|
.addUse(CmpVal)
|
|
|
|
.addUse(NewVal)
|
|
|
|
.addMemOperand(&MMO);
|
|
|
|
}
|
|
|
|
|
2019-07-31 07:56:30 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildAtomicRMW(
|
|
|
|
unsigned Opcode, const DstOp &OldValRes,
|
|
|
|
const SrcOp &Addr, const SrcOp &Val,
|
|
|
|
MachineMemOperand &MMO) {
|
|
|
|
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
#ifndef NDEBUG
|
2019-07-31 07:56:30 +08:00
|
|
|
LLT OldValResTy = OldValRes.getLLTTy(*getMRI());
|
|
|
|
LLT AddrTy = Addr.getLLTTy(*getMRI());
|
|
|
|
LLT ValTy = Val.getLLTTy(*getMRI());
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
assert(OldValResTy.isScalar() && "invalid operand type");
|
|
|
|
assert(AddrTy.isPointer() && "invalid operand type");
|
|
|
|
assert(ValTy.isValid() && "invalid operand type");
|
|
|
|
assert(OldValResTy == ValTy && "type mismatch");
|
2019-07-31 07:56:30 +08:00
|
|
|
assert(MMO.isAtomic() && "not atomic mem operand");
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
#endif
|
|
|
|
|
2019-07-31 07:56:30 +08:00
|
|
|
auto MIB = buildInstr(Opcode);
|
|
|
|
OldValRes.addDefToMIB(*getMRI(), MIB);
|
|
|
|
Addr.addSrcToMIB(MIB);
|
|
|
|
Val.addSrcToMIB(MIB);
|
|
|
|
MIB.addMemOperand(&MMO);
|
|
|
|
return MIB;
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWXchg(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XCHG, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWAdd(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_ADD, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWSub(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_SUB, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWAnd(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_AND, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWNand(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_NAND, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildAtomicRMWOr(Register OldValRes,
|
|
|
|
Register Addr,
|
|
|
|
Register Val,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_OR, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWXor(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XOR, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWMax(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MAX, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWMin(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MIN, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWUmax(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMAX, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildAtomicRMWUmin(Register OldValRes, Register Addr,
|
|
|
|
Register Val, MachineMemOperand &MMO) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMIN, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
|
2019-07-31 07:56:30 +08:00
|
|
|
MachineInstrBuilder
|
|
|
|
MachineIRBuilder::buildAtomicRMWFAdd(
|
|
|
|
const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
|
|
|
|
MachineMemOperand &MMO) {
|
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_FADD, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder
|
|
|
|
MachineIRBuilder::buildAtomicRMWFSub(const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
|
|
|
|
MachineMemOperand &MMO) {
|
|
|
|
return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_FSUB, OldValRes, Addr, Val,
|
|
|
|
MMO);
|
|
|
|
}
|
|
|
|
|
2018-07-31 08:08:50 +08:00
|
|
|
MachineInstrBuilder
|
2019-07-02 22:16:39 +08:00
|
|
|
MachineIRBuilder::buildFence(unsigned Ordering, unsigned Scope) {
|
|
|
|
return buildInstr(TargetOpcode::G_FENCE)
|
|
|
|
.addImm(Ordering)
|
|
|
|
.addImm(Scope);
|
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineIRBuilder::buildBlockAddress(Register Res, const BlockAddress *BA) {
|
2018-07-31 08:08:50 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
assert(getMRI()->getType(Res).isPointer() && "invalid res type");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA);
|
|
|
|
}
|
|
|
|
|
2020-02-14 03:30:50 +08:00
|
|
|
void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy,
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
bool IsExtend) {
|
2016-08-24 06:14:15 +08:00
|
|
|
#ifndef NDEBUG
|
2016-08-24 05:01:33 +08:00
|
|
|
if (DstTy.isVector()) {
|
[globalisel][irtranslator] Add support for atomicrmw and (strong) cmpxchg
Summary:
This patch adds support for the atomicrmw instructions and the strong
cmpxchg instruction to the IRTranslator.
I've left out weak cmpxchg because LangRef.rst isn't entirely clear on what
difference it makes to the backend. As far as I can tell from the code, it
only matters to AtomicExpandPass which is run at the LLVM-IR level.
Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar, volkan, javed.absar
Reviewed By: qcolombet
Subscribers: kristof.beyls, javed.absar, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D40092
llvm-svn: 336589
2018-07-10 03:33:40 +08:00
|
|
|
assert(SrcTy.isVector() && "mismatched cast between vector and non-vector");
|
2016-08-24 05:01:33 +08:00
|
|
|
assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
|
|
|
|
"different number of elements in a trunc/ext");
|
|
|
|
} else
|
|
|
|
assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
|
|
|
|
|
|
|
|
if (IsExtend)
|
|
|
|
assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
|
|
|
|
"invalid narrowing extend");
|
|
|
|
else
|
|
|
|
assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
|
|
|
|
"invalid widening trunc");
|
2016-08-24 06:14:15 +08:00
|
|
|
#endif
|
2016-08-24 05:01:33 +08:00
|
|
|
}
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
|
2020-02-14 03:30:50 +08:00
|
|
|
void MachineIRBuilder::validateSelectOp(const LLT ResTy, const LLT TstTy,
|
|
|
|
const LLT Op0Ty, const LLT Op1Ty) {
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
|
|
|
|
"invalid operand type");
|
|
|
|
assert((ResTy == Op0Ty && ResTy == Op1Ty) && "type mismatch");
|
|
|
|
if (ResTy.isScalar() || ResTy.isPointer())
|
|
|
|
assert(TstTy.isScalar() && "type mismatch");
|
|
|
|
else
|
|
|
|
assert((TstTy.isScalar() ||
|
|
|
|
(TstTy.isVector() &&
|
|
|
|
TstTy.getNumElements() == Op0Ty.getNumElements())) &&
|
|
|
|
"type mismatch");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
|
|
|
|
ArrayRef<DstOp> DstOps,
|
2018-12-12 04:04:40 +08:00
|
|
|
ArrayRef<SrcOp> SrcOps,
|
|
|
|
Optional<unsigned> Flags) {
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
switch (Opc) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case TargetOpcode::G_SELECT: {
|
|
|
|
assert(DstOps.size() == 1 && "Invalid select");
|
|
|
|
assert(SrcOps.size() == 3 && "Invalid select");
|
|
|
|
validateSelectOp(
|
|
|
|
DstOps[0].getLLTTy(*getMRI()), SrcOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[1].getLLTTy(*getMRI()), SrcOps[2].getLLTTy(*getMRI()));
|
|
|
|
break;
|
|
|
|
}
|
2020-08-11 17:50:58 +08:00
|
|
|
case TargetOpcode::G_FNEG:
|
|
|
|
case TargetOpcode::G_ABS:
|
|
|
|
// All these are unary ops.
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(SrcOps.size() == 1 && "Invalid Srcs");
|
|
|
|
validateUnaryOp(DstOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()));
|
|
|
|
break;
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
case TargetOpcode::G_ADD:
|
|
|
|
case TargetOpcode::G_AND:
|
|
|
|
case TargetOpcode::G_MUL:
|
|
|
|
case TargetOpcode::G_OR:
|
|
|
|
case TargetOpcode::G_SUB:
|
|
|
|
case TargetOpcode::G_XOR:
|
|
|
|
case TargetOpcode::G_UDIV:
|
|
|
|
case TargetOpcode::G_SDIV:
|
|
|
|
case TargetOpcode::G_UREM:
|
2019-05-18 02:36:31 +08:00
|
|
|
case TargetOpcode::G_SREM:
|
|
|
|
case TargetOpcode::G_SMIN:
|
|
|
|
case TargetOpcode::G_SMAX:
|
|
|
|
case TargetOpcode::G_UMIN:
|
[GlobalISel] Add generic opcodes for saturating add/subtract
Summary:
Add new generic MIR opcodes G_SADDSAT etc. Add support in IRTranslator
for translating the saturating add/subtract intrinsics to the new
opcodes.
Reviewers: aemerson, dsanders, paquette, arsenm
Subscribers: jvesely, wdng, nhaehnle, rovka, hiraditya, volkan, kerbowa, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D76600
2020-02-24 19:13:05 +08:00
|
|
|
case TargetOpcode::G_UMAX:
|
|
|
|
case TargetOpcode::G_UADDSAT:
|
|
|
|
case TargetOpcode::G_SADDSAT:
|
|
|
|
case TargetOpcode::G_USUBSAT:
|
|
|
|
case TargetOpcode::G_SSUBSAT: {
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
// All these are binary ops.
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(SrcOps.size() == 2 && "Invalid Srcs");
|
|
|
|
validateBinaryOp(DstOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[1].getLLTTy(*getMRI()));
|
|
|
|
break;
|
2019-02-08 03:37:44 +08:00
|
|
|
}
|
|
|
|
case TargetOpcode::G_SHL:
|
|
|
|
case TargetOpcode::G_ASHR:
|
[Intrinsic] Add sshl.sat/ushl.sat, saturated shift intrinsics.
Summary:
This patch adds two intrinsics, llvm.sshl.sat and llvm.ushl.sat,
which perform signed and unsigned saturating left shift,
respectively.
These are useful for implementing the Embedded-C fixed point
support in Clang, originally discussed in
http://lists.llvm.org/pipermail/llvm-dev/2018-August/125433.html
and
http://lists.llvm.org/pipermail/cfe-dev/2018-May/058019.html
Reviewers: leonardchan, craig.topper, bjope, jdoerfert
Subscribers: hiraditya, jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83216
2020-07-16 23:02:04 +08:00
|
|
|
case TargetOpcode::G_LSHR:
|
|
|
|
case TargetOpcode::G_USHLSAT:
|
|
|
|
case TargetOpcode::G_SSHLSAT: {
|
2019-02-08 03:37:44 +08:00
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(SrcOps.size() == 2 && "Invalid Srcs");
|
|
|
|
validateShiftOp(DstOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[1].getLLTTy(*getMRI()));
|
|
|
|
break;
|
|
|
|
}
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
case TargetOpcode::G_SEXT:
|
|
|
|
case TargetOpcode::G_ZEXT:
|
|
|
|
case TargetOpcode::G_ANYEXT:
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(SrcOps.size() == 1 && "Invalid Srcs");
|
|
|
|
validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()), true);
|
|
|
|
break;
|
|
|
|
case TargetOpcode::G_TRUNC:
|
2019-02-08 03:37:44 +08:00
|
|
|
case TargetOpcode::G_FPTRUNC: {
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(SrcOps.size() == 1 && "Invalid Srcs");
|
|
|
|
validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()), false);
|
|
|
|
break;
|
|
|
|
}
|
2020-01-29 05:09:12 +08:00
|
|
|
case TargetOpcode::G_BITCAST: {
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(SrcOps.size() == 1 && "Invalid Srcs");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() && "invalid bitcast");
|
|
|
|
break;
|
|
|
|
}
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
case TargetOpcode::COPY:
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
2019-03-19 05:29:21 +08:00
|
|
|
// If the caller wants to add a subreg source it has to be done separately
|
|
|
|
// so we may not have any SrcOps at this point yet.
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
break;
|
|
|
|
case TargetOpcode::G_FCMP:
|
|
|
|
case TargetOpcode::G_ICMP: {
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst Operands");
|
|
|
|
assert(SrcOps.size() == 3 && "Invalid Src Operands");
|
|
|
|
// For F/ICMP, the first src operand is the predicate, followed by
|
|
|
|
// the two comparands.
|
|
|
|
assert(SrcOps[0].getSrcOpKind() == SrcOp::SrcType::Ty_Predicate &&
|
|
|
|
"Expecting predicate");
|
|
|
|
assert([&]() -> bool {
|
|
|
|
CmpInst::Predicate Pred = SrcOps[0].getPredicate();
|
|
|
|
return Opc == TargetOpcode::G_ICMP ? CmpInst::isIntPredicate(Pred)
|
|
|
|
: CmpInst::isFPPredicate(Pred);
|
|
|
|
}() && "Invalid predicate");
|
|
|
|
assert(SrcOps[1].getLLTTy(*getMRI()) == SrcOps[2].getLLTTy(*getMRI()) &&
|
|
|
|
"Type mismatch");
|
|
|
|
assert([&]() -> bool {
|
|
|
|
LLT Op0Ty = SrcOps[1].getLLTTy(*getMRI());
|
|
|
|
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
|
|
|
|
if (Op0Ty.isScalar() || Op0Ty.isPointer())
|
|
|
|
return DstTy.isScalar();
|
|
|
|
else
|
|
|
|
return DstTy.isVector() &&
|
|
|
|
DstTy.getNumElements() == Op0Ty.getNumElements();
|
|
|
|
}() && "Type Mismatch");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_UNMERGE_VALUES: {
|
|
|
|
assert(!DstOps.empty() && "Invalid trivial sequence");
|
|
|
|
assert(SrcOps.size() == 1 && "Invalid src for Unmerge");
|
|
|
|
assert(std::all_of(DstOps.begin(), DstOps.end(),
|
|
|
|
[&, this](const DstOp &Op) {
|
|
|
|
return Op.getLLTTy(*getMRI()) ==
|
|
|
|
DstOps[0].getLLTTy(*getMRI());
|
|
|
|
}) &&
|
|
|
|
"type mismatch in output list");
|
|
|
|
assert(DstOps.size() * DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
|
|
|
|
"input operands do not cover output register");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_MERGE_VALUES: {
|
|
|
|
assert(!SrcOps.empty() && "invalid trivial sequence");
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst");
|
|
|
|
assert(std::all_of(SrcOps.begin(), SrcOps.end(),
|
|
|
|
[&, this](const SrcOp &Op) {
|
|
|
|
return Op.getLLTTy(*getMRI()) ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI());
|
|
|
|
}) &&
|
|
|
|
"type mismatch in input list");
|
|
|
|
assert(SrcOps.size() * SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
|
|
|
|
"input operands do not cover output register");
|
|
|
|
if (SrcOps.size() == 1)
|
|
|
|
return buildCast(DstOps[0], SrcOps[0]);
|
2019-10-12 04:22:47 +08:00
|
|
|
if (DstOps[0].getLLTTy(*getMRI()).isVector()) {
|
|
|
|
if (SrcOps[0].getLLTTy(*getMRI()).isVector())
|
|
|
|
return buildInstr(TargetOpcode::G_CONCAT_VECTORS, DstOps, SrcOps);
|
|
|
|
return buildInstr(TargetOpcode::G_BUILD_VECTOR, DstOps, SrcOps);
|
|
|
|
}
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
|
|
|
|
assert(DstOps.size() == 1 && "Invalid Dst size");
|
|
|
|
assert(SrcOps.size() == 2 && "Invalid Src size");
|
|
|
|
assert(SrcOps[0].getLLTTy(*getMRI()).isVector() && "Invalid operand type");
|
|
|
|
assert((DstOps[0].getLLTTy(*getMRI()).isScalar() ||
|
|
|
|
DstOps[0].getLLTTy(*getMRI()).isPointer()) &&
|
|
|
|
"Invalid operand type");
|
|
|
|
assert(SrcOps[1].getLLTTy(*getMRI()).isScalar() && "Invalid operand type");
|
|
|
|
assert(SrcOps[0].getLLTTy(*getMRI()).getElementType() ==
|
|
|
|
DstOps[0].getLLTTy(*getMRI()) &&
|
|
|
|
"Type mismatch");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_INSERT_VECTOR_ELT: {
|
|
|
|
assert(DstOps.size() == 1 && "Invalid dst size");
|
|
|
|
assert(SrcOps.size() == 3 && "Invalid src size");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()).isVector() && "Invalid operand type");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).getElementType() ==
|
|
|
|
SrcOps[1].getLLTTy(*getMRI()) &&
|
|
|
|
"Type mismatch");
|
|
|
|
assert(SrcOps[2].getLLTTy(*getMRI()).isScalar() && "Invalid index");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).getNumElements() ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()).getNumElements() &&
|
|
|
|
"Type mismatch");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_BUILD_VECTOR: {
|
|
|
|
assert((!SrcOps.empty() || SrcOps.size() < 2) &&
|
|
|
|
"Must have at least 2 operands");
|
|
|
|
assert(DstOps.size() == 1 && "Invalid DstOps");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
|
|
|
|
"Res type must be a vector");
|
|
|
|
assert(std::all_of(SrcOps.begin(), SrcOps.end(),
|
|
|
|
[&, this](const SrcOp &Op) {
|
|
|
|
return Op.getLLTTy(*getMRI()) ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI());
|
|
|
|
}) &&
|
|
|
|
"type mismatch in input list");
|
|
|
|
assert(SrcOps.size() * SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
|
2019-01-27 08:53:54 +08:00
|
|
|
"input scalars do not exactly cover the output vector register");
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_BUILD_VECTOR_TRUNC: {
|
|
|
|
assert((!SrcOps.empty() || SrcOps.size() < 2) &&
|
|
|
|
"Must have at least 2 operands");
|
|
|
|
assert(DstOps.size() == 1 && "Invalid DstOps");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
|
|
|
|
"Res type must be a vector");
|
|
|
|
assert(std::all_of(SrcOps.begin(), SrcOps.end(),
|
|
|
|
[&, this](const SrcOp &Op) {
|
|
|
|
return Op.getLLTTy(*getMRI()) ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI());
|
|
|
|
}) &&
|
|
|
|
"type mismatch in input list");
|
|
|
|
if (SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
DstOps[0].getLLTTy(*getMRI()).getElementType().getSizeInBits())
|
|
|
|
return buildInstr(TargetOpcode::G_BUILD_VECTOR, DstOps, SrcOps);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_CONCAT_VECTORS: {
|
|
|
|
assert(DstOps.size() == 1 && "Invalid DstOps");
|
|
|
|
assert((!SrcOps.empty() || SrcOps.size() < 2) &&
|
|
|
|
"Must have at least 2 operands");
|
|
|
|
assert(std::all_of(SrcOps.begin(), SrcOps.end(),
|
|
|
|
[&, this](const SrcOp &Op) {
|
|
|
|
return (Op.getLLTTy(*getMRI()).isVector() &&
|
|
|
|
Op.getLLTTy(*getMRI()) ==
|
|
|
|
SrcOps[0].getLLTTy(*getMRI()));
|
|
|
|
}) &&
|
|
|
|
"type mismatch in input list");
|
|
|
|
assert(SrcOps.size() * SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
|
|
|
|
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
|
2019-01-27 08:53:54 +08:00
|
|
|
"input vectors do not exactly cover the output vector register");
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TargetOpcode::G_UADDE: {
|
|
|
|
assert(DstOps.size() == 2 && "Invalid no of dst operands");
|
|
|
|
assert(SrcOps.size() == 3 && "Invalid no of src operands");
|
|
|
|
assert(DstOps[0].getLLTTy(*getMRI()).isScalar() && "Invalid operand");
|
|
|
|
assert((DstOps[0].getLLTTy(*getMRI()) == SrcOps[0].getLLTTy(*getMRI())) &&
|
|
|
|
(DstOps[0].getLLTTy(*getMRI()) == SrcOps[1].getLLTTy(*getMRI())) &&
|
|
|
|
"Invalid operand");
|
|
|
|
assert(DstOps[1].getLLTTy(*getMRI()).isScalar() && "Invalid operand");
|
|
|
|
assert(DstOps[1].getLLTTy(*getMRI()) == SrcOps[2].getLLTTy(*getMRI()) &&
|
|
|
|
"type mismatch");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto MIB = buildInstr(Opc);
|
|
|
|
for (const DstOp &Op : DstOps)
|
|
|
|
Op.addDefToMIB(*getMRI(), MIB);
|
|
|
|
for (const SrcOp &Op : SrcOps)
|
|
|
|
Op.addSrcToMIB(MIB);
|
2018-12-12 04:04:40 +08:00
|
|
|
if (Flags)
|
|
|
|
MIB->setFlags(*Flags);
|
[GISel]: Refactor MachineIRBuilder to allow passing additional parameters to build Instrs
https://reviews.llvm.org/D55294
Previously MachineIRBuilder::buildInstr used to accept variadic
arguments for sources (which were either unsigned or
MachineInstrBuilder). While this worked well in common cases, it doesn't
allow us to build instructions that have multiple destinations.
Additionally passing in other optional parameters in the end (such as
flags) is not possible trivially. Also a trivial call such as
B.buildInstr(Opc, Reg1, Reg2, Reg3)
can be interpreted differently based on the opcode (2defs + 1 src for
unmerge vs 1 def + 2srcs).
This patch refactors the buildInstr to
buildInstr(Opc, ArrayRef<DstOps>, ArrayRef<SrcOps>)
where DstOps and SrcOps are typed unions that know how to add itself to
MachineInstrBuilder.
After this patch, most invocations would look like
B.buildInstr(Opc, {s32, DstReg}, {SrcRegs..., SrcMIBs..});
Now all the other calls (such as buildAdd, buildSub etc) forward to
buildInstr. It also makes it possible to build instructions with
multiple defs.
Additionally in a subsequent patch, we should make it possible to add
flags directly while building instructions.
Additionally, the main buildInstr method is now virtual and other
builders now only have to override buildInstr (for say constant
folding/cseing) is straightforward.
Also attached here (https://reviews.llvm.org/F7675680) is a clang-tidy
patch that should upgrade the API calls if necessary.
llvm-svn: 348815
2018-12-11 08:48:50 +08:00
|
|
|
return MIB;
|
|
|
|
}
|