일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- v8 optimizing
- on-stack replacement
- on stack replacement
- Linux custom packer
- thread local storage
- Linux packer
- anti debugging
- 난독화
- tracerpid
- Android
- linux debugging
- v8 tracing
- Obfuscator
- so inject
- 안티디버깅
- pinpoint
- initial-exec
- custom packer
- LLVM Obfuscator
- uftrace
- TLS
- android inject
- pthread
- tracing
- LLVM 난독화
- linux thread
- OSR
- Injection
- LLVM
- apm
Archives
- Today
- Total
Why should I know this?
SubclassOptionalData 본문
LLVM 에는 최적화를 위한 부가 데이터가 있다.
value.h
protected:
/// Hold subclass data that can be dropped.
///
/// This member is similar to SubclassData, however it is for holding
/// information which may be used to aid optimization, but which may be
/// cleared to zero without affecting conservative interpretation.
unsigned char SubclassOptionalData : 7;
SubClassOptionalData
or disjoint
disjoint는 or 최적화를 위한 부가정보를 담고 있다.
/// An or instruction, which can be marked as "disjoint", indicating that the
/// inputs don't have a 1 in the same bit position. Meaning this instruction
/// can also be treated as an add.
class PossiblyDisjointInst : public BinaryOperator {
주석의 설명과 같이 disjoint는 or의 두 인자가 서로 다른 비트로 구성되어 있는 경우에 세팅되게 된다.
최근에 disjoint 를 적용한 패치
https://github.com/llvm/llvm-project/pull/74467
패치 본문에 나오는 것처럼
case Instruction::Or: {
// Convert or disjoint into add nuw nsw.
if (cast<PossiblyDisjointInst>(Op)->isDisjoint())
return BinaryOp(Instruction::Add, Op->getOperand(0), Op->getOperand(1),
/*IsNSW=*/true, /*IsNUW=*/true);
return BinaryOp(Op);
}
or이 disjoint인 경우 Add 연산을 리턴하는 코드이다.
이전코드는 직접 비트를 검사했었다.
case Instruction::Or: {
// LLVM loves to convert `add` of operands with no common bits
// into an `or`. But SCEV really doesn't deal with `or` that well,
// so try extra hard to recognize this `or` as an `add`.
if (haveNoCommonBitsSet(Op->getOperand(0), Op->getOperand(1),
SimplifyQuery(DL, &DT, &AC, CxtI)))
return BinaryOp(Instruction::Add, Op->getOperand(0), Op->getOperand(1),
/*IsNSW=*/true, /*IsNUW=*/true);
return BinaryOp(Op);
}
disjoint 는 다음과 같이 세팅되거나
InstCombineSimplifyDemanded.cpp:267
// Infer disjoint flag if no common bits are set.
if (!cast<PossiblyDisjointInst>(I)->isDisjoint()) {
WithCache<const Value *> LHSCache(I->getOperand(0), LHSKnown),
RHSCache(I->getOperand(1), RHSKnown);
if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(I))) {
cast<PossiblyDisjointInst>(I)->setIsDisjoint(true);
return I;
}
}
다음처럼 최적화 과정에서 생성된다.
InstCombineSimplifyDemanded.cpp:311
// If all of the demanded bits are known to be zero on one side or the
// other, turn this into an *inclusive* or.
// e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
if (DemandedMask.isSubsetOf(RHSKnown.Zero | LHSKnown.Zero)) {
Instruction *Or =
BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1));
if (DemandedMask.isAllOnes())
cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
Or->takeName(I);
return InsertNewInstWith(Or, I->getIterator());
}
'LLVM-STUDY' 카테고리의 다른 글
LLVM 내부에서 활용되는 논리식 모음 (0) | 2023.12.15 |
---|---|
[TODO] DomConditionCache (0) | 2023.12.11 |
computeKnownBits & KnownBits 관련 예제 (0) | 2023.12.05 |
byval (0) | 2023.11.07 |
LLVM Study 관련 팁 (0) | 2023.10.25 |
Comments