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"
|
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
|
|
|
}
|
|
|
|
|
[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::setMBB(MachineBasicBlock &MBB) {
|
2018-04-10 01:30:56 +08:00
|
|
|
State.MBB = &MBB;
|
|
|
|
State.II = MBB.end();
|
2016-02-12 01:44:59 +08:00
|
|
|
assert(&getMF() == MBB.getParent() &&
|
|
|
|
"Basic block is in a different function");
|
|
|
|
}
|
|
|
|
|
[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::setInstr(MachineInstr &MI) {
|
2016-02-12 01:44:59 +08:00
|
|
|
assert(MI.getParent() && "Instruction is not part of a basic block");
|
2016-03-12 01:27:47 +08:00
|
|
|
setMBB(*MI.getParent());
|
2018-04-10 01:30:56 +08:00
|
|
|
State.II = MI.getIterator();
|
2016-02-12 01:44:59 +08:00
|
|
|
}
|
|
|
|
|
2019-01-16 08:40:37 +08:00
|
|
|
void MachineIRBuilder::setCSEInfo(GISelCSEInfo *Info) { State.CSEInfo = Info; }
|
|
|
|
|
[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::setInsertPt(MachineBasicBlock &MBB,
|
|
|
|
MachineBasicBlock::iterator II) {
|
2016-12-08 05:05:38 +08:00
|
|
|
assert(MBB.getParent() == &getMF() &&
|
|
|
|
"Basic block is in a different function");
|
2018-04-10 01:30:56 +08:00
|
|
|
State.MBB = &MBB;
|
|
|
|
State.II = II;
|
2016-02-12 01:44:59 +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
|
|
|
void MachineIRBuilder::recordInsertion(MachineInstr *InsertedInstr) const {
|
2018-12-06 04:14:52 +08:00
|
|
|
if (State.Observer)
|
|
|
|
State.Observer->createdInstr(*InsertedInstr);
|
2018-05-10 01:28: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
|
|
|
void MachineIRBuilder::setChangeObserver(GISelChangeObserver &Observer) {
|
2018-12-06 04:14:52 +08:00
|
|
|
State.Observer = &Observer;
|
2016-08-26 01:37:32 +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
|
|
|
void MachineIRBuilder::stopObservingChanges() { State.Observer = nullptr; }
|
2016-08-26 01:37:32 +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::buildInstr(unsigned Opcode) {
|
2016-09-22 21:49:25 +08:00
|
|
|
return insertInstr(buildInstrNoInsert(Opcode));
|
|
|
|
}
|
|
|
|
|
[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");
|
[DebugInfo] Remove some users of DBG_VALUEs IsIndirect field
This patch kills off a significant user of the "IsIndirect" field of
DBG_VALUE machine insts. Brought up in in PR41675, IsIndirect is
techncally redundant as it can be expressed by the DIExpression of a
DBG_VALUE inst, and it isn't helpful to have two ways of expressing
things.
Rather than setting IsIndirect, have DBG_VALUE creators add an extra deref
to the insts DIExpression. There should now be no appearences of
IsIndirect=True from isel down to LiveDebugVariables / VirtRegRewriter,
which is ensured by an assertion in LDVImpl::handleDebugValue. This means
we also get to delete the IsIndirect handling in LiveDebugVariables. Tests
can be upgraded by for example swapping the following IsIndirect=True
DBG_VALUE:
DBG_VALUE $somereg, 0, !123, !DIExpression(DW_OP_foo)
With one where the indirection is in the DIExpression, by _appending_
a deref:
DBG_VALUE $somereg, $noreg, !123, !DIExpression(DW_OP_foo, DW_OP_deref)
Which both mean the same thing.
Most of the test changes in this patch are updates of that form; also some
changes in how the textual assembly printer handles these insts.
Differential Revision: https://reviews.llvm.org/D68945
llvm-svn: 374877
2019-10-15 18:46:24 +08:00
|
|
|
// DBG_VALUE insts now carry IR-level indirection in their DIExpression
|
|
|
|
// rather than encoding it in the instruction itself.
|
|
|
|
const DIExpression *DIExpr = cast<DIExpression>(Expr);
|
|
|
|
DIExpr = DIExpression::append(DIExpr, {dwarf::DW_OP_deref});
|
2018-04-10 01:30:56 +08:00
|
|
|
return insertInstr(BuildMI(getMF(), getDL(),
|
|
|
|
getTII().get(TargetOpcode::DBG_VALUE),
|
[DebugInfo] Remove some users of DBG_VALUEs IsIndirect field
This patch kills off a significant user of the "IsIndirect" field of
DBG_VALUE machine insts. Brought up in in PR41675, IsIndirect is
techncally redundant as it can be expressed by the DIExpression of a
DBG_VALUE inst, and it isn't helpful to have two ways of expressing
things.
Rather than setting IsIndirect, have DBG_VALUE creators add an extra deref
to the insts DIExpression. There should now be no appearences of
IsIndirect=True from isel down to LiveDebugVariables / VirtRegRewriter,
which is ensured by an assertion in LDVImpl::handleDebugValue. This means
we also get to delete the IsIndirect handling in LiveDebugVariables. Tests
can be upgraded by for example swapping the following IsIndirect=True
DBG_VALUE:
DBG_VALUE $somereg, 0, !123, !DIExpression(DW_OP_foo)
With one where the indirection is in the DIExpression, by _appending_
a deref:
DBG_VALUE $somereg, $noreg, !123, !DIExpression(DW_OP_foo, DW_OP_deref)
Which both mean the same thing.
Most of the test changes in this patch are updates of that form; also some
changes in how the textual assembly printer handles these insts.
Differential Revision: https://reviews.llvm.org/D68945
llvm-svn: 374877
2019-10-15 18:46:24 +08:00
|
|
|
/*IsIndirect*/ false, Reg, Variable, DIExpr));
|
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");
|
[DebugInfo] Remove some users of DBG_VALUEs IsIndirect field
This patch kills off a significant user of the "IsIndirect" field of
DBG_VALUE machine insts. Brought up in in PR41675, IsIndirect is
techncally redundant as it can be expressed by the DIExpression of a
DBG_VALUE inst, and it isn't helpful to have two ways of expressing
things.
Rather than setting IsIndirect, have DBG_VALUE creators add an extra deref
to the insts DIExpression. There should now be no appearences of
IsIndirect=True from isel down to LiveDebugVariables / VirtRegRewriter,
which is ensured by an assertion in LDVImpl::handleDebugValue. This means
we also get to delete the IsIndirect handling in LiveDebugVariables. Tests
can be upgraded by for example swapping the following IsIndirect=True
DBG_VALUE:
DBG_VALUE $somereg, 0, !123, !DIExpression(DW_OP_foo)
With one where the indirection is in the DIExpression, by _appending_
a deref:
DBG_VALUE $somereg, $noreg, !123, !DIExpression(DW_OP_foo, DW_OP_deref)
Which both mean the same thing.
Most of the test changes in this patch are updates of that form; also some
changes in how the textual assembly printer handles these insts.
Differential Revision: https://reviews.llvm.org/D68945
llvm-svn: 374877
2019-10-15 18:46:24 +08:00
|
|
|
// DBG_VALUE insts now carry IR-level indirection in their DIExpression
|
|
|
|
// rather than encoding it in the instruction itself.
|
|
|
|
const DIExpression *DIExpr = cast<DIExpression>(Expr);
|
|
|
|
DIExpr = DIExpression::append(DIExpr, {dwarf::DW_OP_deref});
|
2017-01-27 07:39:14 +08:00
|
|
|
return buildInstr(TargetOpcode::DBG_VALUE)
|
|
|
|
.addFrameIndex(FI)
|
[DebugInfo] Remove some users of DBG_VALUEs IsIndirect field
This patch kills off a significant user of the "IsIndirect" field of
DBG_VALUE machine insts. Brought up in in PR41675, IsIndirect is
techncally redundant as it can be expressed by the DIExpression of a
DBG_VALUE inst, and it isn't helpful to have two ways of expressing
things.
Rather than setting IsIndirect, have DBG_VALUE creators add an extra deref
to the insts DIExpression. There should now be no appearences of
IsIndirect=True from isel down to LiveDebugVariables / VirtRegRewriter,
which is ensured by an assertion in LDVImpl::handleDebugValue. This means
we also get to delete the IsIndirect handling in LiveDebugVariables. Tests
can be upgraded by for example swapping the following IsIndirect=True
DBG_VALUE:
DBG_VALUE $somereg, 0, !123, !DIExpression(DW_OP_foo)
With one where the indirection is in the DIExpression, by _appending_
a deref:
DBG_VALUE $somereg, $noreg, !123, !DIExpression(DW_OP_foo, DW_OP_deref)
Which both mean the same thing.
Most of the test changes in this patch are updates of that form; also some
changes in how the textual assembly printer handles these insts.
Differential Revision: https://reviews.llvm.org/D68945
llvm-svn: 374877
2019-10-15 18:46:24 +08:00
|
|
|
.addReg(0)
|
2017-01-27 07:39:14 +08:00
|
|
|
.addMetadata(Variable)
|
[DebugInfo] Remove some users of DBG_VALUEs IsIndirect field
This patch kills off a significant user of the "IsIndirect" field of
DBG_VALUE machine insts. Brought up in in PR41675, IsIndirect is
techncally redundant as it can be expressed by the DIExpression of a
DBG_VALUE inst, and it isn't helpful to have two ways of expressing
things.
Rather than setting IsIndirect, have DBG_VALUE creators add an extra deref
to the insts DIExpression. There should now be no appearences of
IsIndirect=True from isel down to LiveDebugVariables / VirtRegRewriter,
which is ensured by an assertion in LDVImpl::handleDebugValue. This means
we also get to delete the IsIndirect handling in LiveDebugVariables. Tests
can be upgraded by for example swapping the following IsIndirect=True
DBG_VALUE:
DBG_VALUE $somereg, 0, !123, !DIExpression(DW_OP_foo)
With one where the indirection is in the DIExpression, by _appending_
a deref:
DBG_VALUE $somereg, $noreg, !123, !DIExpression(DW_OP_foo, DW_OP_deref)
Which both mean the same thing.
Most of the test changes in this patch are updates of that form; also some
changes in how the textual assembly printer handles these insts.
Differential Revision: https://reviews.llvm.org/D68945
llvm-svn: 374877
2019-10-15 18:46:24 +08:00
|
|
|
.addMetadata(DIExpr);
|
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");
|
2017-01-27 07:39:14 +08:00
|
|
|
auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
|
|
|
|
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 {
|
|
|
|
// Insert %noreg if we didn't find a usable constant and had to drop it.
|
|
|
|
MIB.addReg(0U);
|
|
|
|
}
|
2017-01-27 07:39:14 +08:00
|
|
|
|
[DebugInfo] Remove some users of DBG_VALUEs IsIndirect field
This patch kills off a significant user of the "IsIndirect" field of
DBG_VALUE machine insts. Brought up in in PR41675, IsIndirect is
techncally redundant as it can be expressed by the DIExpression of a
DBG_VALUE inst, and it isn't helpful to have two ways of expressing
things.
Rather than setting IsIndirect, have DBG_VALUE creators add an extra deref
to the insts DIExpression. There should now be no appearences of
IsIndirect=True from isel down to LiveDebugVariables / VirtRegRewriter,
which is ensured by an assertion in LDVImpl::handleDebugValue. This means
we also get to delete the IsIndirect handling in LiveDebugVariables. Tests
can be upgraded by for example swapping the following IsIndirect=True
DBG_VALUE:
DBG_VALUE $somereg, 0, !123, !DIExpression(DW_OP_foo)
With one where the indirection is in the DIExpression, by _appending_
a deref:
DBG_VALUE $somereg, $noreg, !123, !DIExpression(DW_OP_foo, DW_OP_deref)
Which both mean the same thing.
Most of the test changes in this patch are updates of that form; also some
changes in how the textual assembly printer handles these insts.
Differential Revision: https://reviews.llvm.org/D68945
llvm-svn: 374877
2019-10-15 18:46:24 +08:00
|
|
|
return MIB.addReg(0).addMetadata(Variable).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::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,
|
|
|
|
unsigned Align) {
|
|
|
|
assert(Res.getLLTTy(*getMRI()).isPointer() && "expected ptr dst type");
|
|
|
|
auto MIB = buildInstr(TargetOpcode::G_DYN_STACKALLOC);
|
|
|
|
Res.addDefToMIB(*getMRI(), MIB);
|
|
|
|
Size.addSrcToMIB(MIB);
|
|
|
|
MIB.addImm(Align);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
[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::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
|
|
|
}
|
|
|
|
|
2019-02-08 03:37:44 +08:00
|
|
|
void MachineIRBuilder::validateShiftOp(const LLT &Res, const LLT &Op0,
|
|
|
|
const LLT &Op1) {
|
|
|
|
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) {
|
2019-07-09 00:27:47 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).isPointer() &&
|
|
|
|
Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch");
|
|
|
|
assert(Op1.getLLTTy(*getMRI()).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,
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildPtrMask(const DstOp &Res,
|
|
|
|
const SrcOp &Op0,
|
[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
|
|
|
uint32_t NumBits) {
|
2019-07-09 00:27:47 +08:00
|
|
|
assert(Res.getLLTTy(*getMRI()).isPointer() &&
|
|
|
|
Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch");
|
2017-02-15 04:56:18 +08:00
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
auto MIB = buildInstr(TargetOpcode::G_PTR_MASK);
|
|
|
|
Res.addDefToMIB(*getMRI(), MIB);
|
|
|
|
Op0.addSrcToMIB(MIB);
|
|
|
|
MIB.addImm(NumBits);
|
|
|
|
return MIB;
|
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);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-06-28 09:16:41 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildBrCond(Register 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) {
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(getMRI()->getType(Tst).isScalar() && "invalid operand type");
|
2016-09-09 19:46:58 +08:00
|
|
|
|
2016-09-09 19:46:34 +08:00
|
|
|
return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
|
2016-07-30 01:58:00 +08:00
|
|
|
}
|
|
|
|
|
2019-07-09 00:27:47 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildLoad(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) {
|
[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
|
|
|
return buildLoadInstr(TargetOpcode::G_LOAD, Res, 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::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
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2019-03-11 18:00:17 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildUAddo(const DstOp &Res,
|
|
|
|
const DstOp &CarryOut,
|
|
|
|
const SrcOp &Op0,
|
|
|
|
const SrcOp &Op1) {
|
|
|
|
return buildInstr(TargetOpcode::G_UADDO, {Res, CarryOut}, {Op0, Op1});
|
|
|
|
}
|
|
|
|
|
[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::buildUAdde(const DstOp &Res,
|
|
|
|
const DstOp &CarryOut,
|
|
|
|
const SrcOp &Op0,
|
|
|
|
const SrcOp &Op1,
|
|
|
|
const SrcOp &CarryIn) {
|
|
|
|
return buildInstr(TargetOpcode::G_UADDE, {Res, CarryOut},
|
|
|
|
{Op0, Op1, CarryIn});
|
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::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");
|
2016-08-31 04:51:25 +08:00
|
|
|
assert(std::is_sorted(Indices.begin(), Indices.end()) &&
|
|
|
|
"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
|
|
|
}
|
|
|
|
|
[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
|
|
|
}
|
|
|
|
|
2019-06-24 23:50:29 +08:00
|
|
|
MachineInstrBuilder MachineIRBuilder::buildInsert(Register Res, Register Src,
|
|
|
|
Register Op, unsigned Index) {
|
2018-04-10 01:30:56 +08:00
|
|
|
assert(Index + getMRI()->getType(Op).getSizeInBits() <=
|
|
|
|
getMRI()->getType(Res).getSizeInBits() &&
|
2017-06-28 06:45:35 +08:00
|
|
|
"insertion past the end of a register");
|
|
|
|
|
2018-04-10 01:30:56 +08:00
|
|
|
if (getMRI()->getType(Res).getSizeInBits() ==
|
|
|
|
getMRI()->getType(Op).getSizeInBits()) {
|
2017-03-07 03:04:17 +08:00
|
|
|
return buildCast(Res, Op);
|
|
|
|
}
|
|
|
|
|
2017-03-04 07:05:47 +08:00
|
|
|
return buildInstr(TargetOpcode::G_INSERT)
|
|
|
|
.addDef(Res)
|
|
|
|
.addUse(Src)
|
|
|
|
.addUse(Op)
|
|
|
|
.addImm(Index);
|
|
|
|
}
|
|
|
|
|
[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);
|
|
|
|
}
|
|
|
|
|
[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::validateTruncExt(const LLT &DstTy, const LLT &SrcTy,
|
|
|
|
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
|
|
|
|
|
|
|
void MachineIRBuilder::validateSelectOp(const LLT &ResTy, const LLT &TstTy,
|
|
|
|
const LLT &Op0Ty, const LLT &Op1Ty) {
|
|
|
|
#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;
|
|
|
|
}
|
|
|
|
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:
|
|
|
|
case TargetOpcode::G_UMAX: {
|
[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:
|
|
|
|
case TargetOpcode::G_LSHR: {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|