The two main operations in terms of CPU usage are determining if an output is sent to you (is_out_to_acc_precomp, defined in src/cryptonote_basic/cryptonote_format_utils.cpp) and generating the key derivations that is_out_to_acc_precomp acts on (generate_key_derivation, defined in src/crypto/crypto.cpp). There is some threading there, but it could still be sped up.
Both of those end up calling low level crypto functions, such that a profile looks like this:
18.00% monero-wallet-cli [.] fe_sq
17.54% monero-wallet-cli [.] fe_cmov
3.21% monero-wallet-cli [.] fe_invert
3.08% monero-wallet-cli [.] fe_divpowm1
2.86% monero-wallet-cli [.] fe_sq2
2.35% monero-wallet-cli [.] fe_add
1.75% monero-wallet-cli [.] select
1.62% monero-wallet-cli [.] keccakf
1.16% monero-wallet-cli [.] ge_p2_dbl
0.97% monero-wallet-cli [.] ge_scalarmult_base
0.80% monero-wallet-cli [.] ge_scalarmult
There are a couple asm versions of those, which proved to give some substantial speedup too, see https://github.com/monero-project/monero/pull/2317