From f0ad3e4093b3dbd64aafd661b074ce694a2a2ff0 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 28 Aug 2019 11:18:47 +0000 Subject: [PATCH 1/3] [lldb][NFC] Test custom C++ operators llvm-svn: 370186 --- .../test/lang/cpp/operators/Makefile | 3 + .../lang/cpp/operators/TestCppOperators.py | 5 + .../test/lang/cpp/operators/main.cpp | 142 ++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/operators/Makefile create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py create mode 100644 lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/Makefile new file mode 100644 index 0000000000000..99bfa7e03b479 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py new file mode 100644 index 0000000000000..293e913963709 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), + lldbinline.expectedFailureAll(oslist=["windows"])) diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp new file mode 100644 index 0000000000000..5376a277995aa --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp @@ -0,0 +1,142 @@ +struct B { int dummy = 2324; }; +struct C { + B b; + B* operator->() { return &b; } + int operator->*(int) { return 2; } + int operator+(int) { return 44; } + int operator+=(int) { return 42; } + int operator++(int) { return 123; } + int operator++() { return 1234; } + int operator-(int) { return 34; } + int operator-=(int) { return 32; } + int operator--() { return 321; } + int operator--(int) { return 4321; } + + int operator*(int) { return 51; } + int operator*=(int) { return 52; } + int operator%(int) { return 53; } + int operator%=(int) { return 54; } + int operator/(int) { return 55; } + int operator/=(int) { return 56; } + int operator^(int) { return 57; } + int operator^=(int) { return 58; } + + int operator|(int) { return 61; } + int operator|=(int) { return 62; } + int operator||(int) { return 63; } + int operator&(int) { return 64; } + int operator&=(int) { return 65; } + int operator&&(int) { return 66; } + + int operator~() { return 71; } + int operator!() { return 72; } + int operator!=(int) { return 73; } + int operator=(int) { return 74; } + int operator==(int) { return 75; } + + int operator<(int) { return 81; } + int operator<<(int) { return 82; } + int operator<=(int) { return 83; } + int operator<<=(int) { return 84; } + int operator>(int) { return 85; } + int operator>>(int) { return 86; } + int operator>=(int) { return 87; } + int operator>>=(int) { return 88; } + + int operator[](int) { return 91; } + int operator()(int) { return 92; } +}; + +int main(int argc, char **argv) { + C c; + int result = c->dummy; + result = c->*4; + result += c+1; + result += c+=1; + result += c++; + result += ++c; + result += c-1; + result += c-=1; + result += c--; + result += --c; + + result += c * 4; + result += c *= 4; + result += c % 4; + result += c %= 4; + result += c / 4; + result += c /= 4; + result += c ^ 4; + result += c ^= 4; + + result += c | 4; + result += c |= 4; + result += c || 4; + result += c & 4; + result += c &= 4; + result += c && 4; + + result += ~c; + result += !c; + result += c!=1; + result += c=2; + result += c==2; + + result += c<2; + result += c<<2; + result += c<=2; + result += c<<=2; + result += c>2; + result += c>>2; + result += c>=2; + result += c>>=2; + + result += c(1); + result += c[1]; + //% self.expect("expr c->dummy", endstr=" 2324\n") + //% self.expect("expr c->*2", endstr=" 2\n") + //% self.expect("expr c + 44", endstr=" 44\n") + //% self.expect("expr c += 42", endstr=" 42\n") + //% self.expect("expr c++", endstr=" 123\n") + //% self.expect("expr ++c", endstr=" 1234\n") + + //% self.expect("expr c - 34", endstr=" 34\n") + //% self.expect("expr c -= 32", endstr=" 32\n") + //% self.expect("expr c--", endstr=" 321\n") + //% self.expect("expr --c", endstr=" 4321\n") + + //% self.expect("expr c * 3", endstr=" 51\n") + //% self.expect("expr c *= 3", endstr=" 52\n") + //% self.expect("expr c % 3", endstr=" 53\n") + //% self.expect("expr c %= 3", endstr=" 54\n") + //% self.expect("expr c / 3", endstr=" 55\n") + //% self.expect("expr c /= 3", endstr=" 56\n") + //% self.expect("expr c ^ 3", endstr=" 57\n") + //% self.expect("expr c ^= 3", endstr=" 58\n") + + //% self.expect("expr c | 3", endstr=" 61\n") + //% self.expect("expr c |= 3", endstr=" 62\n") + //% self.expect("expr c || 3", endstr=" 63\n") + //% self.expect("expr c & 3", endstr=" 64\n") + //% self.expect("expr c &= 3", endstr=" 65\n") + //% self.expect("expr c && 3", endstr=" 66\n") + + //% self.expect("expr ~c", endstr=" 71\n") + //% self.expect("expr !c", endstr=" 72\n") + //% self.expect("expr c!=1", endstr=" 73\n") + //% self.expect("expr c=1", endstr=" 74\n") + //% self.expect("expr c==1", endstr=" 75\n") + + //% self.expect("expr c<1", endstr=" 81\n") + //% self.expect("expr c<<1", endstr=" 82\n") + //% self.expect("expr c<=1", endstr=" 83\n") + //% self.expect("expr c<<=1", endstr=" 84\n") + //% self.expect("expr c>1", endstr=" 85\n") + //% self.expect("expr c>>1", endstr=" 86\n") + //% self.expect("expr c>=1", endstr=" 87\n") + //% self.expect("expr c>>=1", endstr=" 88\n") + + //% self.expect("expr c(1)", endstr=" 91\n") + //% self.expect("expr c[1]", endstr=" 92\n") + return 0; +} From 379f6186dd68c61b386dc7fcd78071893b245a36 Mon Sep 17 00:00:00 2001 From: David Green Date: Wed, 28 Aug 2019 11:37:31 +0000 Subject: [PATCH 2/3] [ARM] Move MVEVPTBlockPass to a separate file. NFC This just pulls the MVEVPTBlockPass into a separate file, as opposed to being wrapped up in Thumb2ITBlockPass. Differential revision: https://reviews.llvm.org/D66579 llvm-svn: 370187 --- llvm/lib/Target/ARM/CMakeLists.txt | 1 + llvm/lib/Target/ARM/MVEVPTBlockPass.cpp | 172 ++++++++++++++++++++++ llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp | 143 ------------------ 3 files changed, 173 insertions(+), 143 deletions(-) create mode 100644 llvm/lib/Target/ARM/MVEVPTBlockPass.cpp diff --git a/llvm/lib/Target/ARM/CMakeLists.txt b/llvm/lib/Target/ARM/CMakeLists.txt index 586b6ea45358a..74d43124a027a 100644 --- a/llvm/lib/Target/ARM/CMakeLists.txt +++ b/llvm/lib/Target/ARM/CMakeLists.txt @@ -52,6 +52,7 @@ add_llvm_target(ARMCodeGen ARMTargetObjectFile.cpp ARMTargetTransformInfo.cpp MLxExpansionPass.cpp + MVEVPTBlockPass.cpp Thumb1FrameLowering.cpp Thumb1InstrInfo.cpp ThumbRegisterInfo.cpp diff --git a/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp b/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp new file mode 100644 index 0000000000000..78061170541a9 --- /dev/null +++ b/llvm/lib/Target/ARM/MVEVPTBlockPass.cpp @@ -0,0 +1,172 @@ +//===-- MVEVPTBlockPass.cpp - Insert MVE VPT blocks -----------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "ARM.h" +#include "ARMMachineFunctionInfo.h" +#include "ARMSubtarget.h" +#include "MCTargetDesc/ARMBaseInfo.h" +#include "Thumb2InstrInfo.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineInstrBundle.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCRegisterInfo.h" +#include +#include + +using namespace llvm; + +#define DEBUG_TYPE "arm-mve-vpt" + +namespace { + class MVEVPTBlock : public MachineFunctionPass { + public: + static char ID; + const Thumb2InstrInfo *TII; + const TargetRegisterInfo *TRI; + + MVEVPTBlock() : MachineFunctionPass(ID) {} + + bool runOnMachineFunction(MachineFunction &Fn) override; + + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoVRegs); + } + + StringRef getPassName() const override { + return "MVE VPT block insertion pass"; + } + + private: + bool InsertVPTBlocks(MachineBasicBlock &MBB); + }; + + char MVEVPTBlock::ID = 0; + +} // end anonymous namespace + +INITIALIZE_PASS(MVEVPTBlock, DEBUG_TYPE, "ARM MVE VPT block pass", false, false) + +enum VPTMaskValue { + T = 8, // 0b1000 + TT = 4, // 0b0100 + TE = 12, // 0b1100 + TTT = 2, // 0b0010 + TTE = 6, // 0b0110 + TEE = 10, // 0b1010 + TET = 14, // 0b1110 + TTTT = 1, // 0b0001 + TTTE = 3, // 0b0011 + TTEE = 5, // 0b0101 + TTET = 7, // 0b0111 + TEEE = 9, // 0b1001 + TEET = 11, // 0b1011 + TETT = 13, // 0b1101 + TETE = 15 // 0b1111 +}; + +bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) { + bool Modified = false; + MachineBasicBlock::iterator MBIter = Block.begin(); + MachineBasicBlock::iterator EndIter = Block.end(); + + while (MBIter != EndIter) { + MachineInstr *MI = &*MBIter; + unsigned PredReg = 0; + DebugLoc dl = MI->getDebugLoc(); + + ARMVCC::VPTCodes Pred = getVPTInstrPredicate(*MI, PredReg); + + // The idea of the predicate is that None, Then and Else are for use when + // handling assembly language: they correspond to the three possible + // suffixes "", "t" and "e" on the mnemonic. So when instructions are read + // from assembly source or disassembled from object code, you expect to see + // a mixture whenever there's a long VPT block. But in code generation, we + // hope we'll never generate an Else as input to this pass. + assert(Pred != ARMVCC::Else && "VPT block pass does not expect Else preds"); + + if (Pred == ARMVCC::None) { + ++MBIter; + continue; + } + + MachineInstrBuilder MIBuilder = + BuildMI(Block, MBIter, dl, TII->get(ARM::MVE_VPST)); + + MachineBasicBlock::iterator VPSTInsertPos = MIBuilder.getInstr(); + int VPTInstCnt = 1; + ARMVCC::VPTCodes NextPred; + + do { + ++MBIter; + NextPred = getVPTInstrPredicate(*MBIter, PredReg); + } while (NextPred != ARMVCC::None && NextPred == Pred && ++VPTInstCnt < 4); + + switch (VPTInstCnt) { + case 1: + MIBuilder.addImm(VPTMaskValue::T); + break; + case 2: + MIBuilder.addImm(VPTMaskValue::TT); + break; + case 3: + MIBuilder.addImm(VPTMaskValue::TTT); + break; + case 4: + MIBuilder.addImm(VPTMaskValue::TTTT); + break; + default: + llvm_unreachable("Unexpected number of instruction in a VPT block"); + }; + + MachineInstr *LastMI = &*MBIter; + finalizeBundle(Block, VPSTInsertPos.getInstrIterator(), + ++LastMI->getIterator()); + + Modified = true; + LLVM_DEBUG(dbgs() << "VPT block created for: "; MI->dump()); + + ++MBIter; + } + return Modified; +} + +bool MVEVPTBlock::runOnMachineFunction(MachineFunction &Fn) { + const ARMSubtarget &STI = + static_cast(Fn.getSubtarget()); + + if (!STI.isThumb2() || !STI.hasMVEIntegerOps()) + return false; + + TII = static_cast(STI.getInstrInfo()); + TRI = STI.getRegisterInfo(); + + LLVM_DEBUG(dbgs() << "********** ARM MVE VPT BLOCKS **********\n" + << "********** Function: " << Fn.getName() << '\n'); + + bool Modified = false; + for (MachineBasicBlock &MBB : Fn) + Modified |= InsertVPTBlocks(MBB); + + LLVM_DEBUG(dbgs() << "**************************************\n"); + return Modified; +} + +/// createMVEVPTBlock - Returns an instance of the MVE VPT block +/// insertion pass. +FunctionPass *llvm::createMVEVPTBlockPass() { return new MVEVPTBlock(); } diff --git a/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp b/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp index 3bf0c527427d7..786fc78d0233b 100644 --- a/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp +++ b/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp @@ -308,146 +308,3 @@ bool Thumb2ITBlock::runOnMachineFunction(MachineFunction &Fn) { /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks /// insertion pass. FunctionPass *llvm::createThumb2ITBlockPass() { return new Thumb2ITBlock(); } - -#undef DEBUG_TYPE -#define DEBUG_TYPE "arm-mve-vpt" - -namespace { - class MVEVPTBlock : public MachineFunctionPass { - public: - static char ID; - const Thumb2InstrInfo *TII; - const TargetRegisterInfo *TRI; - - MVEVPTBlock() : MachineFunctionPass(ID) {} - - bool runOnMachineFunction(MachineFunction &Fn) override; - - MachineFunctionProperties getRequiredProperties() const override { - return MachineFunctionProperties().set( - MachineFunctionProperties::Property::NoVRegs); - } - - StringRef getPassName() const override { - return "MVE VPT block insertion pass"; - } - - private: - bool InsertVPTBlocks(MachineBasicBlock &MBB); - }; - - char MVEVPTBlock::ID = 0; - -} // end anonymous namespace - -INITIALIZE_PASS(MVEVPTBlock, DEBUG_TYPE, "ARM MVE VPT block pass", false, false) - -enum VPTMaskValue { - T = 8, // 0b1000 - TT = 4, // 0b0100 - TE = 12, // 0b1100 - TTT = 2, // 0b0010 - TTE = 6, // 0b0110 - TEE = 10, // 0b1010 - TET = 14, // 0b1110 - TTTT = 1, // 0b0001 - TTTE = 3, // 0b0011 - TTEE = 5, // 0b0101 - TTET = 7, // 0b0111 - TEEE = 9, // 0b1001 - TEET = 11, // 0b1011 - TETT = 13, // 0b1101 - TETE = 15 // 0b1111 -}; - -bool MVEVPTBlock::InsertVPTBlocks(MachineBasicBlock &Block) { - bool Modified = false; - MachineBasicBlock::iterator MBIter = Block.begin(); - MachineBasicBlock::iterator EndIter = Block.end(); - - while (MBIter != EndIter) { - MachineInstr *MI = &*MBIter; - unsigned PredReg = 0; - DebugLoc dl = MI->getDebugLoc(); - - ARMVCC::VPTCodes Pred = getVPTInstrPredicate(*MI, PredReg); - - // The idea of the predicate is that None, Then and Else are for use when - // handling assembly language: they correspond to the three possible - // suffixes "", "t" and "e" on the mnemonic. So when instructions are read - // from assembly source or disassembled from object code, you expect to see - // a mixture whenever there's a long VPT block. But in code generation, we - // hope we'll never generate an Else as input to this pass. - - assert(Pred != ARMVCC::Else && "VPT block pass does not expect Else preds"); - - if (Pred == ARMVCC::None) { - ++MBIter; - continue; - } - - MachineInstrBuilder MIBuilder = - BuildMI(Block, MBIter, dl, TII->get(ARM::MVE_VPST)); - - MachineBasicBlock::iterator VPSTInsertPos = MIBuilder.getInstr(); - int VPTInstCnt = 1; - ARMVCC::VPTCodes NextPred; - - do { - ++MBIter; - NextPred = getVPTInstrPredicate(*MBIter, PredReg); - } while (NextPred != ARMVCC::None && NextPred == Pred && ++VPTInstCnt < 4); - - switch (VPTInstCnt) { - case 1: - MIBuilder.addImm(VPTMaskValue::T); - break; - case 2: - MIBuilder.addImm(VPTMaskValue::TT); - break; - case 3: - MIBuilder.addImm(VPTMaskValue::TTT); - break; - case 4: - MIBuilder.addImm(VPTMaskValue::TTTT); - break; - default: - llvm_unreachable("Unexpected number of instruction in a VPT block"); - }; - - MachineInstr *LastMI = &*MBIter; - finalizeBundle(Block, VPSTInsertPos.getInstrIterator(), - ++LastMI->getIterator()); - - Modified = true; - LLVM_DEBUG(dbgs() << "VPT block created for: "; MI->dump()); - - ++MBIter; - } - return Modified; -} - -bool MVEVPTBlock::runOnMachineFunction(MachineFunction &Fn) { - const ARMSubtarget &STI = - static_cast(Fn.getSubtarget()); - - if (!STI.isThumb2() || !STI.hasMVEIntegerOps()) - return false; - - TII = static_cast(STI.getInstrInfo()); - TRI = STI.getRegisterInfo(); - - LLVM_DEBUG(dbgs() << "********** ARM MVE VPT BLOCKS **********\n" - << "********** Function: " << Fn.getName() << '\n'); - - bool Modified = false; - for (MachineBasicBlock &MBB : Fn) - Modified |= InsertVPTBlocks(MBB); - - LLVM_DEBUG(dbgs() << "**************************************\n"); - return Modified; -} - -/// createMVEVPTBlock - Returns an instance of the MVE VPT block -/// insertion pass. -FunctionPass *llvm::createMVEVPTBlockPass() { return new MVEVPTBlock(); } From d2f58545679380ec58a813e3b276723511d373e4 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 28 Aug 2019 11:42:20 +0000 Subject: [PATCH 3/3] gn build: Merge r370187 llvm-svn: 370188 --- llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn index a7d3bda5f31d4..e082f85191fa5 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn @@ -94,6 +94,7 @@ static_library("LLVMARMCodeGen") { "ARMTargetObjectFile.cpp", "ARMTargetTransformInfo.cpp", "MLxExpansionPass.cpp", + "MVEVPTBlockPass.cpp", "Thumb1FrameLowering.cpp", "Thumb1InstrInfo.cpp", "Thumb2ITBlockPass.cpp",