mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-11 13:26:08 +03:00
Clarify some non-obvious points wrt. binops/binassign
This commit is contained in:
parent
951040cc36
commit
2a0a6631a8
2 changed files with 43 additions and 44 deletions
|
@ -249,9 +249,8 @@ DValue *binMod(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <llvm::Instruction::BinaryOps binOp>
|
DValue *binBitwise(llvm::Instruction::BinaryOps binOp, Loc &loc, Type *type,
|
||||||
DValue *binBitwise(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *lhs, Expression *rhs, bool loadLhsAfterRhs) {
|
||||||
bool loadLhsAfterRhs) {
|
|
||||||
auto rvals = evalSides(lhs, rhs, loadLhsAfterRhs);
|
auto rvals = evalSides(lhs, rhs, loadLhsAfterRhs);
|
||||||
|
|
||||||
LLValue *l = DtoRVal(DtoCast(loc, rvals.lhs, type));
|
LLValue *l = DtoRVal(DtoCast(loc, rvals.lhs, type));
|
||||||
|
@ -264,41 +263,39 @@ DValue *binBitwise(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
|
|
||||||
DValue *binAnd(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *binAnd(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
bool loadLhsAfterRhs) {
|
bool loadLhsAfterRhs) {
|
||||||
return binBitwise<llvm::Instruction::And>(loc, type, lhs, rhs,
|
return binBitwise(llvm::Instruction::And, loc, type, lhs, rhs,
|
||||||
loadLhsAfterRhs);
|
loadLhsAfterRhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *binOr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *binOr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
bool loadLhsAfterRhs) {
|
bool loadLhsAfterRhs) {
|
||||||
return binBitwise<llvm::Instruction::Or>(loc, type, lhs, rhs,
|
return binBitwise(llvm::Instruction::Or, loc, type, lhs, rhs,
|
||||||
loadLhsAfterRhs);
|
loadLhsAfterRhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *binXor(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *binXor(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
bool loadLhsAfterRhs) {
|
bool loadLhsAfterRhs) {
|
||||||
return binBitwise<llvm::Instruction::Xor>(loc, type, lhs, rhs,
|
return binBitwise(llvm::Instruction::Xor, loc, type, lhs, rhs,
|
||||||
loadLhsAfterRhs);
|
loadLhsAfterRhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *binShl(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *binShl(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
bool loadLhsAfterRhs) {
|
bool loadLhsAfterRhs) {
|
||||||
return binBitwise<llvm::Instruction::Shl>(loc, type, lhs, rhs,
|
return binBitwise(llvm::Instruction::Shl, loc, type, lhs, rhs,
|
||||||
loadLhsAfterRhs);
|
loadLhsAfterRhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *binShr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *binShr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
bool loadLhsAfterRhs) {
|
bool loadLhsAfterRhs) {
|
||||||
if (isLLVMUnsigned(type))
|
auto op = (isLLVMUnsigned(type) ? llvm::Instruction::LShr
|
||||||
return binUshr(loc, type, lhs, rhs);
|
: llvm::Instruction::AShr);
|
||||||
|
return binBitwise(op, loc, type, lhs, rhs, loadLhsAfterRhs);
|
||||||
return binBitwise<llvm::Instruction::AShr>(loc, type, lhs, rhs,
|
|
||||||
loadLhsAfterRhs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DValue *binUshr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
DValue *binUshr(Loc &loc, Type *type, DValue *lhs, Expression *rhs,
|
||||||
bool loadLhsAfterRhs) {
|
bool loadLhsAfterRhs) {
|
||||||
return binBitwise<llvm::Instruction::LShr>(loc, type, lhs, rhs,
|
return binBitwise(llvm::Instruction::LShr, loc, type, lhs, rhs,
|
||||||
loadLhsAfterRhs);
|
loadLhsAfterRhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
54
gen/toir.cpp
54
gen/toir.cpp
|
@ -560,7 +560,7 @@ public:
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define BIN_OP(Op) \
|
#define BIN_OP(Op, Func) \
|
||||||
void visit(Op##Exp *e) override { \
|
void visit(Op##Exp *e) override { \
|
||||||
IF_LOG Logger::print(#Op "Exp::toElem: %s @ %s\n", e->toChars(), \
|
IF_LOG Logger::print(#Op "Exp::toElem: %s @ %s\n", e->toChars(), \
|
||||||
e->type->toChars()); \
|
e->type->toChars()); \
|
||||||
|
@ -571,21 +571,21 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo; \
|
auto &PGO = gIR->func()->pgo; \
|
||||||
PGO.setCurrentStmt(e); \
|
PGO.setCurrentStmt(e); \
|
||||||
\
|
\
|
||||||
result = bin##Op(e->loc, e->type, toElem(e->e1), e->e2); \
|
result = Func(e->loc, e->type, toElem(e->e1), e->e2); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BIN_OP(Add)
|
BIN_OP(Add, binAdd)
|
||||||
BIN_OP(Min)
|
BIN_OP(Min, binMin)
|
||||||
BIN_OP(Mul)
|
BIN_OP(Mul, binMul)
|
||||||
BIN_OP(Div)
|
BIN_OP(Div, binDiv)
|
||||||
BIN_OP(Mod)
|
BIN_OP(Mod, binMod)
|
||||||
|
|
||||||
BIN_OP(And)
|
BIN_OP(And, binAnd)
|
||||||
BIN_OP(Or)
|
BIN_OP(Or, binOr)
|
||||||
BIN_OP(Xor)
|
BIN_OP(Xor, binXor)
|
||||||
BIN_OP(Shl)
|
BIN_OP(Shl, binShl)
|
||||||
BIN_OP(Shr)
|
BIN_OP(Shr, binShr)
|
||||||
BIN_OP(Ushr)
|
BIN_OP(Ushr, binUshr)
|
||||||
#undef BIN_OP
|
#undef BIN_OP
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -612,7 +612,7 @@ public:
|
||||||
return lhsLVal;
|
return lhsLVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BIN_ASSIGN(Op, useLValTypeForBinOp) \
|
#define BIN_ASSIGN(Op, Func, useLValTypeForBinOp) \
|
||||||
void visit(Op##AssignExp *e) override { \
|
void visit(Op##AssignExp *e) override { \
|
||||||
IF_LOG Logger::print(#Op "AssignExp::toElem: %s @ %s\n", e->toChars(), \
|
IF_LOG Logger::print(#Op "AssignExp::toElem: %s @ %s\n", e->toChars(), \
|
||||||
e->type->toChars()); \
|
e->type->toChars()); \
|
||||||
|
@ -623,21 +623,21 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo; \
|
auto &PGO = gIR->func()->pgo; \
|
||||||
PGO.setCurrentStmt(e); \
|
PGO.setCurrentStmt(e); \
|
||||||
\
|
\
|
||||||
result = binAssign<bin##Op, useLValTypeForBinOp>(e); \
|
result = binAssign<Func, useLValTypeForBinOp>(e); \
|
||||||
}
|
}
|
||||||
|
|
||||||
BIN_ASSIGN(Add, false)
|
BIN_ASSIGN(Add, binAdd, false)
|
||||||
BIN_ASSIGN(Min, false)
|
BIN_ASSIGN(Min, binMin, false)
|
||||||
BIN_ASSIGN(Mul, false)
|
BIN_ASSIGN(Mul, binMul, false)
|
||||||
BIN_ASSIGN(Div, false)
|
BIN_ASSIGN(Div, binDiv, false)
|
||||||
BIN_ASSIGN(Mod, false)
|
BIN_ASSIGN(Mod, binMod, false)
|
||||||
|
|
||||||
BIN_ASSIGN(And, false)
|
BIN_ASSIGN(And, binAnd, false)
|
||||||
BIN_ASSIGN(Or, false)
|
BIN_ASSIGN(Or, binOr, false)
|
||||||
BIN_ASSIGN(Xor, false)
|
BIN_ASSIGN(Xor, binXor, false)
|
||||||
BIN_ASSIGN(Shl, true)
|
BIN_ASSIGN(Shl, binShl, true)
|
||||||
BIN_ASSIGN(Shr, true)
|
BIN_ASSIGN(Shr, binShr, true)
|
||||||
BIN_ASSIGN(Ushr, true)
|
BIN_ASSIGN(Ushr, binUshr, true)
|
||||||
#undef BIN_ASSIGN
|
#undef BIN_ASSIGN
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1747,6 +1747,7 @@ public:
|
||||||
llvm::BranchInst::Create(andandend, p->scopebb());
|
llvm::BranchInst::Create(andandend, p->scopebb());
|
||||||
p->scope() = IRScope(andandend);
|
p->scope() = IRScope(andandend);
|
||||||
|
|
||||||
|
// DMD allows stuff like `x == 0 && assert(false)`
|
||||||
if (e->type->toBasetype()->ty == Tvoid) {
|
if (e->type->toBasetype()->ty == Tvoid) {
|
||||||
result = nullptr;
|
result = nullptr;
|
||||||
return;
|
return;
|
||||||
|
@ -1808,6 +1809,7 @@ public:
|
||||||
llvm::BranchInst::Create(ororend, p->scopebb());
|
llvm::BranchInst::Create(ororend, p->scopebb());
|
||||||
p->scope() = IRScope(ororend);
|
p->scope() = IRScope(ororend);
|
||||||
|
|
||||||
|
// DMD allows stuff like `x == 0 || assert(false)`
|
||||||
if (e->type->toBasetype()->ty == Tvoid) {
|
if (e->type->toBasetype()->ty == Tvoid) {
|
||||||
result = nullptr;
|
result = nullptr;
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue