Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from llvm:master #19

Merged
merged 3 commits into from
Aug 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from lldbsuite.test import lldbinline
from lldbsuite.test import decorators

lldbinline.MakeInlineTest(__file__, globals(),
lldbinline.expectedFailureAll(oslist=["windows"]))
142 changes: 142 additions & 0 deletions lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions llvm/lib/Target/ARM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ add_llvm_target(ARMCodeGen
ARMTargetObjectFile.cpp
ARMTargetTransformInfo.cpp
MLxExpansionPass.cpp
MVEVPTBlockPass.cpp
Thumb1FrameLowering.cpp
Thumb1InstrInfo.cpp
ThumbRegisterInfo.cpp
Expand Down
172 changes: 172 additions & 0 deletions llvm/lib/Target/ARM/MVEVPTBlockPass.cpp
Original file line number Diff line number Diff line change
@@ -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 <cassert>
#include <new>

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<const ARMSubtarget &>(Fn.getSubtarget());

if (!STI.isThumb2() || !STI.hasMVEIntegerOps())
return false;

TII = static_cast<const Thumb2InstrInfo *>(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(); }
Loading